2019-03-17-13:17于杭州
当别人问起来什么是Promise/A+
规范,可能会觉得有点懵,你可能用过Promise
,但很可能不了解什么是Promise
规范。
其实Promise
规范有很多,如Promise/A
,Promise/B
,Promise/D
以及 Promise/A
的升级版 Promise/A+
。ES6中采用了 Promise/A+
规范。
Promise标准解读
记住两点
(1) 一个promise的当前状态只能是pending
、fulfilled
和rejected
三种之一。状态改变只能是pending
到fulfilled
或者pending
到rejected
。状态改变不可逆。
(2) promise的then
方法接收两个可选参数,表示该promise
状态改变时的回调(promise.then(onFulfilled, onRejected))。then
方法返回一个promise
,then
方法可以被同一个 promise 调用多次。
Promise/A+并未规范race
、all
、catch
方法,这些是ES6
自己规范的。
下面来重点讲讲Promise
原理
promise
采用了观察者模式,用特定方式 注册 对应 状态 的事件处理函数!!!
雏型:
function Promise(fn) {
var value = null,
callbacks = []; //callbacks为数组,因为可能同时有很多个回调
this.then = function (onFulfilled) {
callbacks.push(onFulfilled);
};
function resolve(value) {
callbacks.forEach(function (callback) {
callback(value);
});
}
fn(resolve);
}
1、实现链式调用then
原理:递归
/**
* 处理promise递归的函数
*
* promiseRef {Promise} promise实例
* result {*} promise回调函数处理的结果
* resolve {function} 成功回调
* reject {function} 失败回调
*/
function handlePromise(promiseRef, result, resolve, reject) {
if(promiseRef === result) { // promise resolve()中的参数如果是本身就无限循环了
return reject(new TypeError("circle refrence"))
}
// 递归条件
if(result !== null &&(typeof result === "object" || typeof result === "function")) {
let called; // promise状态只能更改一次
try {
let then = result.then;
if(typeof then === "function") { // result是promise对象
then.call(result, param => {
if(called) return
called = true;
handlePromise(promiseRef, param, resolve, reject) // 递归解析promise
}, err => {
if(called) return;
called = true;
reject(err);
})
} else { // reuslt只是普通js对象
resolve(result)
}
}catch(e) {
if(called) return;
called = true;
reject(e);
}
} else { // 基本类型
resolve(result)
}
}
将then
方法放到Promise
内的callbacks
数组 中(有可能有多个then),当resolve
之后去forEach
循环执行
catch
相当于 this.then(null,onRejected)
race
赛跑
一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
// Both resolve, but promise2 is faster
}); // 打印 "two"