谈谈我对Promise的理解
⼀、Promise是什么?
Promise是最早由社区提出和实现的⼀种解决异步编程的⽅案,⽐其他传统的解决⽅案(回调函数和事件)更合理和更强⼤。
ES6 将其写进了语⾔标准,统⼀了⽤法,原⽣提供了Promise对象。
ES6 规定,Promise对象是⼀个构造函数,⽤来⽣成Promise实例。
⼆、Promise是为解决什么问题⽽产⽣的?
promise是为解决异步处理回调⾦字塔问题⽽产⽣的
三、Promise的两个特点
1、Promise对象的状态不受外界影响
1)pending 初始状态
2)fulfilled 成功状态
3)rejected 失败状态
Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪⼀种状态,其他任何操作都⽆法改变这个状态
2、Promise的状态⼀旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected
四、Promise的三个缺点
1)⽆法取消Promise,⼀旦新建它就会⽴即执⾏,⽆法中途取消
2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
3)当处于pending状态时,⽆法得知⽬前进展到哪⼀个阶段,是刚刚开始还是即将完成
五、Promise在哪存放成功回调序列和失败回调序列?
1)onResolvedCallbacks 成功后要执⾏的回调序列是⼀个数组
2)onRejectedCallbacks 失败后要执⾏的回调序列是⼀个数组
以上两个数组存放在Promise 创建实例时给Promise这个类传的函数中,默认都是空数组。
每次实例then的时候传⼊ onFulfilled 成功回调 onRejected 失败回调,如果此时的状态是pending 则将onFulfilled和onRejected push到对应的成功回调序列数组和失败回调序列
数组中,如果此时的状态是fulfilled 则onFulfilled⽴即执⾏,如果此时的状态是rejected则onRejected⽴即执⾏
上述序列中的回调函数执⾏的时候是有顺序的,即按照顺序依次执⾏
六、Promise的⽤法
1、Promise构造函数接受⼀个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不⽤⾃⼰部署。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
2、resolve函数的作⽤是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调⽤,并将异步操作的结果,作为参数传递出去;
reject函数的作⽤是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调⽤,并将异步操作报出的错误,作为参数传递出去。
3、Promise实例⽣成以后,可以⽤then⽅法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then⽅法可以接受两个回调函数作为参数。第⼀个回调函数是Promise对象的状态变为resolved时调⽤,第⼆个回调函数是Promise对象的状态变为rejected时调⽤。其中,第⼆
个函数是可选的,不⼀定要提供。这两个函数都接受Promise对象传出的值作为参数。
七、按照Promise A+规范写Promise的简单实现原理
// 第⼀步:Promise构造函数接受⼀个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不⽤⾃⼰部署。
function Promise(task) {
let that = this; // 缓存this
that.status = 'pending'; // 进⾏中的状态
that.value = undefined; //初始值
that.RejectedCallbacks = []; // 存放失败后要执⾏的回调函数的序列
// 该⽅法是将Promise由pending变成fulfilled
function resolve (value) {
if (that.status == 'pending') {
that.status = 'fulfilled';
that.value = value;
}
}
/
/ 该⽅法是将Promise由pending变成rejected
function reject (reason) {
if (that.status == 'pending') {
that.status = 'rejected';
that.value = reason;
}
}
try {
// 每⼀个Promise在new⼀个实例的时候接受的函数都是⽴即执⾏的
task(resolve, reject)
} catch (e) {
reject(e)
}
}
// 第⼆部写then⽅法,接收两个函数onFulfilled onRejected,状态是成功态的时候调⽤onFulfilled 传⼊成功后的值,失败态的时候执⾏onRejected,传⼊失败的原因,pending 状态时将成功和失败后的这两个⽅法缓存到对应的数组中,当成功或失败后    Promise.prototype.then = function(onFulfilled, onRejected) {
let that = this;
if (that.status == 'fulfilled') {
onFulfilled(that.value);
}
if (that.status == 'rejected') {
onRejected(that.value);
}
if (that.status == 'pending') {
}
}
⼋、Promise 链式写法
我们先来看⼀个例⼦,根据例⼦得出结论,然后再写源码的实现部分来验证结论
let promise = new Promise(function (resolve, reject) {
resolve(100);// reject(100)
});
promise.then(function (data) {
return data+100;
},function (err) {
return 'ssss';
}).then(function (data) {
console.log(data);// 200  // undefined // sss
})
从上⾯的例⼦可以看出:
当第⼀个promise的成功的回调⾥返回 200时,第⼆个promise的成功回调的参数就是200
当将resolve(100)改成reject(100)的时候,因为失败回调中什么也没有返回所以第⼆个promise的成功回调中的参数是undefined
当失败的回调中返回sss时,第⼆个promise的成功回调中的参数是sss
由此我们可以看出,第⼀个promise不管成功回调还是失败回调,他的返回值作为第⼆个promise中的成功时回调函数的参数值
链式写法能⼀直then下去的原因:链式调⽤靠的是返回新的promise,来保证可以⼀直⾛成功或失败
九、 Promise.catch
Promise.prototype.catch⽅法是.then(null, rejection)的别名,⽤于指定发⽣错误时的回调函数。
//catch原理就是只传失败的回调
resolved是什么状态Promise.prototype.catch = function(onRejected){
this.then(null,onRejected);
}
⼗、 Promise.all ⽅法
参数:接受⼀个数组,数组内都是Promise实例
返回值:返回⼀个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中所有的实例都处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意⼀个实例处于reject状态,返回的Promise实例变为reject状态
Promise.all = function(promises){
return new Promise(function(resolve,reject){
let done = gen(promises.length,resolve);
for(let i=0;i<promises.length;i++){
promises[i].then(function(data){
done(i,data);
},reject);
}
});
}
⼗⼀、solve
返回⼀个Promise实例,这个实例处于resolve状态。
根据传⼊的参数不同有不同的功能:
值(对象、数组、字符串等):作为resolve传递出去的值
Promise实例:原封不动返回
//返回⼀个⽴刻成功的promise
//别⼈提供给你⼀个⽅法,需要你传⼊⼀个promise,但你只有⼀个普通的值,你就可以通过这个⽅法把这个普通的值(string number object)转成⼀个promise对象
return new Promise(function(resolve){
resolve(value);
});
}
⼗⼆、 ject
返回⼀个Promise实例,这个实例处于reject状态。
参数⼀般就是抛出的错误信息。
//返回⼀个⽴刻失败的promise
return new Promise(function(resolve,reject){
reject(reason);
});
}
⼗三、 Promise.race
参数:接受⼀个数组,数组内都是Promise实例
返回值:返回⼀个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中任何⼀个实例处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意⼀个实例处于reject状态,返回的Promise实例变为reject状态。
Promise.race = function(promises){
return new Promise(function(resolve,reject){
for(let i=0;i<promises.length;i++){
promises[i].then(resolve,reject);
}
});
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。