Promise 用法介绍
Promise 函数的参数
new Promise(1); // Promise resolver 1 is not a function
let p = new Promise([executor]);
// [executor]: 可执行函数
// + new Promise 的时候,在 Promise 内部会立即把 executor 函数执行(同步代码)
// + 同时给 [executor] 函数传递两个参数「都是函数类型」:resolve/reject
Promise 的实例
let p = new Promise(function(resolve, reject) {
console.log(1);
});
// p 是 Promise 类的一个实例
// + 内置私有属性(带两个中括号的)
// + [[PromiseState]]: pending fulfilled rejected
// + [[PromiseResult]]: 实例的值
// + 公共的属性方法 Promise.prototype
// + then
// + catch
// + finally
// + Symbol(Symbol.toStringTag): "Promise"
Promise 内部代码报错
如果 [executor] 函数报错,则会把状态变为 rejected,值为报错原因。
var p1 = new Promise((resolve, reject) => {
console.log(xxxxxxxxx); // 报错代码
})
p1.then(null, reason => {
console.log('P1失败 -->', reason);
})
// P1失败 --> ReferenceError: xxxxxxxxx is not defined
then 方法的返回值
var p1 = new Promise((resolve, reject) => {
resolve('OK');
reject('NO');
})
var p2 = p1.then(result => {
console.log('P1成功 -->', result);
// return 10;
}, reason => {
console.log('P1失败 -->', reason);
})
console.log(p2);
// 执行 then 方法会返回一个全新的 promise 实例
// p2 的状态和值是怎么改变的呢?
// + 不论执行的是基于 p1.then 成功还是失败回调
// + 只要方法执行不报错:
// + 如果方法中返回一个全新的 promise 实例,则全新的实例的状态和值会赋予 p2
// + 否则 [[PromiseState]]: fulfiled,[[PromiseResult]]: 返回值
// + 如果方法执行报错:
// + p2 的 [[PromiseState]]: rejected,[[PromiseResult]]: 报错原因
then 接收 null 的顺延机制
如果 onfulfilledCallback/onrejectedCallback 为 null 或者不传递,则状态和结果都会"顺延/穿透"到下一个同等状态的回调函数上「内部是自己补充了一些实现效果的默认函数」
new Promise((resolve, reject) => {
resolve('OK');
}).then(null /* result => result */, reason => {
console.log('第一层失败 -->', reason);
}).then(result => {
console.log('第二层成功 -->', result);
}, reason => {
console.log('第二层失败 -->', reason);
});
// 第二层成功 --> OK
我们发现如果成功回调方法传 null,不会走失败的回调,而是相当于把 null 变成一个 result => result; 函数来顺延到下一层的成功方法去执行,当然 reject 也是一样的表现,不过 reject 是把 null 编程 reason => Promise.reject(reason)。
catch 的使用
其实 catch 本身的实现方式特别简单,只处理失败的情况的变形 then 方法罢了。
Promise.prototype.catch = function(onrejectedCallback) {
return this.then(null, onrejectedCallback);
}
所以我们下面代码是好使的,这也利用了 then 方法省略回调后的穿透效果。
new Promise((resolve, reject) => {
reject('NO');
}).then(result => {
console.log('第一层成功 -->', result);
}).then(result => {
console.log('第二层成功 -->', result);
}).catch(reason => {
console.log('失败 -->', reason);
});
如果成功回调中报错,则会将状态改为 rejected,并把错误原因传递下去。
new Promise((resolve, reject) => {
resolve('OK');
}).then(result => {
console.log('第一层成功 -->', result);
console.log(xxxxxxxx); // 报错了
}).then(result => {
console.log('第二层成功 -->', result);
}).catch(reason => {
console.log('失败 -->', reason);
});
// 第一层成功 --> OK
// 失败 --> ReferenceError: xxxxxxxx is not defined