Promise的用法介绍

65 阅读2分钟

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