Promise
Promise也叫期约,是一种设计模式:承诺模式
Promise在JS中是一个对象,用于表示一个异步操作的最终完成 (或失败)及其结果值。
- 创建一个Promise对象:
let p = new Promise([executor]);
- executor:可执行函数
- new Promise时必须传入这个函数,在Promise内部会立即把 [executor] 函数执行
- 函数中一般用来管理一个异步编程代码(不管控异步编程也是可以的)
- Promise本身是同步执行的,立即将 [executor] 函数执行,只不过内部可以管控异步代码
- 同时给 [executor] 函数传入两个值(函数类型):resolve/reject
let p = new Promise([executor]); p是Promise类的一个实例
- 内置私有属性
- [[PromiseState]] 实例状态:pending准备状态,fulfilled/resolved成功状态,rejected失败状态
- [[PromiseResult]] 实例的值:为 resolve/reject函数的参数的值
- 公共属性方法
- then
- catch
- finally
- Symbol(Symbol.toStringTag): “Promise”
在 [executor] 中执行 resolve/reject 都是为了改变promise实例的状态和值(结果),一旦状态被改变成 fulfilled/rejected 则不能再改变为其他的状态
-
resolve(‘OK’)
- [[PromiseState]]:fulfilled
- [[PromiseResult]]:‘OK’
-
reject(‘NO’)
- [[PromiseState]]:rejected
- [[PromiseResult]]:‘NO’
-
如果 [executor] 函数执行报错,则
- [[PromiseState]]:rejected
- [[PromiseResult]]:报错原因
- Promise内部做了异常信息捕获[try-catch]
let p1 = new Promise((resolve, reject) => { resolve('OK'); reject('NO'); });
实例状态的改变,可以控制.then方法执行;执行then方法时,选择其中存放的两个方法中的某一个方法执行,并且把 [[PromiseResult]] 的值传递给方法
p.then(onfulfilledCallback, onrejectedCallback);
-
状态成功时执行的是:onfullfilledCallback
-
状态失败执行的是:onrejectedCallback
-
一个实例的then方法可以执行多次
let p1 = new Promise((resolve, reject) => { resolve('OK'); }); p1.then(result => { console.log('成功-->', result); }, reason => { console.log('失败-->', reason); }); p1.then(result => { console.log('成功-->', result); }, reason => { console.log('失败-->', reason); });
执行p.then(onfulfilledCallback, onrejectedCallback)
- 首先把传递进来的 onfulfilledCallback 和 onrejectedCallback 存储起来 [存储在一个容器中:因为可以基于then给其存放多个回调函数]
- 其次再去验证当前实例的状态
- 如果实例的状态是pending,则不做任何的处理
- 如果已经变为 fulfilled/rejected 状态,则会通知对应的回调函数执行 [但是不是立即执行,而是把其放置在 EventQueue 中的微任务队列中]
- Promise本身不是异步的,是用来管理异步的,但是then方法是异步的 [微任务]
let p = new Promise((resolve, reject) => { console.log(1); resolve('OK'); //同步修改其状态和结果 console.log(2); }); console.log(p); //此时状态已经修改为成功 p.then(result => { console.log('成功-->', result); }); console.log(3);
执行then方法会返回一个全新的Promise实例p2
-
p2的状态是如何改变的
- 不论执行的是基于p1.then存放的 onfulfilledCallback/onrejectedCallback 两个方法中的哪一个
- 只要方法执行不报错
- 如果方法执行返回一个全新的Promise实例,则全新的Promise实例的成功和失败决定p2的成功和失败
- 如果返回值不是Promise实例,则 [[PromiseState]]:fulfilled [[PromiseResult]]:返回值
- 如果方法执行报错,则 [[PromiseState]]:rejected [[PromiseResult]]:报错原因
- Promise.resolve(‘ok’) 生成一个成功的promise实例
- Promise.reject(‘no’) 生成一个失败的promise实例
let p1 = new Promise((resolve, reject) => { // resolve('OK'); reject('NO'); }); let p2 = p1.then(result => { console.log('成功-->', result); return Promise.reject(10); // return 10; }, reason => { console.log('p1失败-->', reason); }); let p3 = p2.then(result => { console.log('P2成功-->', result); return Promise.resolve(10); }, reason => { console.log('P2失败-->', reason); return Promise.resolve(10); }); p3.then(result => { console.log('P3成功-->', result); return Promise.resolve(10); }, reason => { console.log('P3失败-->', reason); return Promise.resolve(10); });
如果 onfulfilledCallback/onrejectedCallback 不传值,则“状态/结果”都会顺延到下一个同等状态的应该执行的回调函数上
[内部其实是自己补充了一些实现效果的默认函数]
new Promise((resolve, reject) => {
resolve('OK');
// reject('NO');
}).then(null /*相当于result=>result(顺延到下一个then的result)*/,
null /*相当于reason=>Promise.reject(reason) 也是顺延 如果不写,相当于写null*/).then(result => {
console.log('成功-->', result);
}, reason => {
console.log('失败-->', reason);
}).then(result => {
console.log('成功-->', result);
}, reason => {
console.log('失败-->', reason);
});
catch只处理状态为失败下做的事情
相当于:
Promise.prototype.catch = function (onrejectedCallback){
return this.then(null, onrejectedCallback);
};
利用上两条机制,我们可以进行Promise的then链写法:在then方法中只写成功态要做的事情,在catch方法中写失败态要做的事情
new Promise((resolve, reject) => {
// resolve('OK');
reject('NO');
}).then(result => {
console.log('成功-->', result);
}).then(result => {
console.log('成功-->', result);
}).catch(reason => {
console.log('失败-->', reason);
});
Promise.all([promise数组:{要求数组中的每一项尽可能都是promise实例}])
(如果传入的参数不是promise,也会自动调用promise.resolve()转换为promise对象):
返回一个新的promise实例AA,AA成功还是失败,取决于数组中的每一个promise实例是成功还是失败,只要有一个是失败,AA就是失败的,只有都成功,AA才是成功的
- 应用场景:
- ajax并行:有多个ajax请求同时执行,等它们全部执行结束后再执行某个操作
Promise.race([promise数组:{要求数组中的每一项尽可能都是promise实例}]):
返回一个新的promise实例AA,最先知道状态的promise实例,是成功还是失败,决定了AA是成功还是失败