Promise 是ES6中新增的一个内置类,可以有效的处理异步编程。
传统在实现异步操作,并且是串行的模式下,基本上都是回调函数套回调函数,而Promise正好解决这个‘回调地狱’的问题
下面我们正式开始理解promise:
我们创建一个promise的实例
let p1 = new Promise([executor]);
- Promise是一个内置类
- p1是类的一个实例
- executor是传递的回调函数,并且这个回调函数必须传递不然会报错
let p1 = new Promise(); //Uncaught TypeError: Promise resolver undefined is not a function
Promise本身是同步的(为了管理异步编程)
- new Promise的时候会立即把executor函数执行
- 在执行executor函数时传递两个参数分别是:resolve、reject,并且这两个参数都是函数
- 创造了一个promise类的一个实例p1,并且会返回当前promise实例的状态和值
- p1.__proto__中则存放着原型中的内置方法:catch、then等
[[PromiseState]]promie状态:pending准备状态 fulfilled/resolved成功 rejected失败
[[PromiseResult]]promise值:默认是undefined,一般存储成功的结果或者失败的原因
- 在实例中执行resolve函数时会控制实例的状态变为成功,传递的值就是成功的结果
- 执行reject时会控制实例状态变为失败,如果executor中函数执行报错,状态也会变成失败态,并且[[PromiseResult]]中是失败的原因。
let p1 = new Promise((resolve,reject)=>{
resolve(100);//此时实例状态已经改变,下面再执行reject便不会再改变
reject(0);
)
then
- then([A],[B]):基于then方法存放两个回调函数A/B,当promise状态成功则执行A,失败则执行B,并且把[[PromiseResult]]的值传递给对应的函数
- then的存在是为了把当前实例成功或者是失败的结果存储下来,并且返回一个新的promise实例p2
- p2的状态由上一个实例p1基于then存放的A/B来决定
- 无论是函数A还是B执行,只要上一个实例执行不报错则p2的状态都是成功,反之执行报错就是失败
- p2的值为A/B执行的返回值,或者是报错的原因
- 如果A/B返回的是一个新的promise实例,则返回的promise实例的成功失败以及结果,直接决定p2的状态和结果
- p2的状态由上一个实例p1基于then存放的A/B来决定
let p1 = new Promise((resolve, reject) => {
// 管理一个异步操作:根据需求控制promise成功还是失败
setTimeout(() => {
let ran = Math.random();//获取0-1之间随机值
ran < 0.5 ? reject('NO') : resolve('OK');
}, 1000);
});
let p2 = p1.then(result => {
//当p1实例的状态修改为成功时,通知第一个函数执行
console.log(`成功了 ${result}`);
return result;
}, reason => {
//当p1实例的状态修改为失败的时候,通知第二个函数执行
console.log(`失败了 ${reason}`);
return reason;
});
- 只要p2执行不报错,那么p2再执行then方法返回的实例状态就一定是成功
let p1 = new Promise((resolve, reject) => {
reject('NO');
});
let p2 = p1.then(result => {
console.log('成功->', result);
return 10;
}, reason => {
console.log('失败->', reason); //->失败 'NO'
return 20;
});
let p3 = p2.then(result => {
console.log('成功->', result); //->成功 20
}, reason => {
console.log('失败->', reason);
});
- 如果then([A],[B])函数有一个没有传递,则会自动顺延到下一个then中的当前函数 promisesaplus.com/(Promise/A+…
catch
如果说then是处理成功的 catch则是处理失败做什么,一般会写在最后面
Promise.resolve(10).then(result => {
console.log(`成功了 -> ${result}`);
return result * a;
}).then(result => {
console.log(`成功了 -> ${result}`);
return result * a;
}).catch(reason => {
console.log(`失败了 -> ${reason}`);
});
成功了 -> 10
失败了 -> ReferenceError: a is not defined
all
Promise.all:若同时处理多个Promise实例,那么等待所有promise实例都成功,返回的状态才是成功,只要有一个失败,整体状态就是失败
race
Promise.race:多个实例谁先处理完成,先处理完的状态不论是失败还是成功,就是最整体的状态
最后上一道面试题巩固一下,答案放后面了哦
new Promise((resolve, reject) => {
reject(20);
}).then(result => {
console.log(`成功了 -> ${result}`);
return result * 10;
}, reason => {
console.log(`失败了 -> ${reason}`);
return reason / 10;
}).then(result => {
console.log(`成功了 -> ${result}`);
return Promise.reject(result * 10);
}, reason => {
console.log(`失败了 -> ${reason}`);
return reason / 10;
}).then(result => {
console.log(`成功了 -> ${result}`);
return result * 10;
}, reason => { 失败了 -> 20
console.log(`失败了 -> ${reason}`); 成功了 -> 2
return reason / 10; 失败了 -> 20
});