1、产生的原因
传统实现异步的操作,是使用ajax层层嵌套,串行的模式,基本都是回调函数套回调函数,有“回调地狱”的问题
此时我们需要一种优秀的代码管理模式,能够有效的管理异步编程的代码,通过代码管理的思想,让代码开发起来更便捷,维护起来也方便,可读性也强==>JS的设计模式
Promise设计模式就是管理异步编程的
2、new Promise
new Promise()必须要传递一个函数(executor函数),否则报错
new Promise的时候,会发生些什么?
- 会【立即执行】传递的executor函数
- 创造Promise类的一个实例
- [[PromiseState]]promise状态:pending准备状态 fulfilled/resolve成功(已兑现) rejected失败(已拒绝)
- [[PromiseResult]]promise值:默认是undefined,一般存储成功的结果或者失败的原因
- p1.__proto__的原型链指向的事Promise的prototype,可调用方法有:then、catch、finally
- 执行resolve控制实例的状态变为成功,传递的值,为成功的结果;执行reject控制实例的状态变为失败;如果executor中的代码执行报错的话,实例的状态也会变成失败态,[[PromiseResult]]则是报错的原因
Promise是如何管控异步编程的?
- new promise的时候创建一个promise实例,此时在executor函数中管理一套异步的代码
- 后期等异步操作成功或者失败,执行resolve/reject,以此控制promise实例的状态和结果
- 根据状态和结果,就可以控制基于.then注入的两个方法中的哪一个去执行了
- 代码执行顺序
- new Promise
- 执行executor函数,其中设置一个异步定时器
- 执行p1.then注入的两个方法(只是保存起来)
- 等待1000ms
- 执行定时器的回调函数,执行resolve改变promise状态和值
- 通知之前注入基于.then的两个方法中的第一个执行
- 输出 成功-> OK
执行resolve/reject的时候修改状态和值,是同步的
但是!!!
“通知对应注入方法执行”,是异步的
示例:
let p1 = new Promise(resolve => { setTimeout(() => { resolve('OK'); console.log(1); //->(1) //再次说明,不论是否基于THEN注入了方法,执行resolve/reject的时候“修改状态和值”是同步的「立即处理」, //但是“通知对应注入方法执行”的这个任务就是异步操作的「不会立即处理,只是把它排到等待任务队列中, //当其它事情处理完,再次返回头,通知对应注入的方法执行」 }, 1000); }); p1.then(result => { console.log(2); //->(2) });
可创建状态为成功/失败的promise示例,或者.then返回的新实例
注意:不管哪个方法执行,只要执行不报错,新实例的状态就是fulfilled,报错就是rejected
但是如果返回的本身是一个promise实例,则此实例最后的成功或者失败,直接决定.then返回实例的成功和失败「得到的结果也都是一样的」;
//创建一个状态为成功的promise实例
let p1 = new Promise(resolve => {
resolve('OK');
});
//创建promise实例
let p1 = new Promise((resolve, reject) => { reject('NO'); });
//创建.then返回的新实例 let p2 = p1.then(result => { console.log('成功->', result); return 10; }, reason => { console.log('失败->', reason); //->失败 'NO' return 20; }); p2.then(result => { console.log('成功->', result); //->成功 20 }, reason => { console.log('失败->', reason); });
//--------------------------------------------
let p1 = Promise.resolve('OK');
let p2 = p1.then(result => {
console.log('成功->', result); //->成功 'OK'
return Promise.reject('NO'); //返回的promise实例的状态和结果就是最后p2的状态和结果
}, reason => {
console.log('失败->', reason);
return 20;
});
p2.then(result => {
console.log('成功->', result);
}, reason => {
console.log('失败->', reason); //->失败 'NO'
});
对于失败的promie实例,如果没有编写方法处理其结果,则会在控制台抛出异常信息「但是不会阻碍其余的代码执行」
在.then注入方法的时候,如果其中某个方法没有传递,则会顺延到下一个then中具备相同状态需要执行的函数上
同时处理多个Promise实例
Promise.all:等待所有的promise实例都成功,整体返回的状态才是成功,只要有一个失败,整体状态就是失败
Promise.race:看多个实例谁先处理完,先处理完成的状态「不论是失败还是成功」就是最后整体的状态
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。