简要介绍:Promise容许咱们经过链式调用的方式来解决“回调地狱”的问题,特别是在异步过程当中,经过Promise能够保证代码的整洁性和可读性。promise
本文主要介绍一下Promise/A+规范,并在此规范的基础上,本身实现一个Promise。浏览器
在了解Promise规范以前,咱们知道主流的高版本浏览器已经支持ECMA中的Promise.异步
建立一个promise实例:函数
let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("success"); }, 3000); console.log("this is a promise"); }); p1.then(value => { console.log(value); }); // 输出: // 立马打印:this is a promise // 延迟3000ms后打印:success
上述是一个promise的实例,输出内容为,“this is a promise”,延迟3000ms后,输出"success"。this
从上述的例子能够看出,promise方便处理异步操做。此外promise还能够链式的调用:prototype
let p2 = new Promise((resolve, reject) => { resolve(); }); p2.then(...).then(...).then(...);
此外Promise除了then方法外,还提供了Promise.resolve、Promise.all、Promise.race等等方法。code
Promise/A+规范大体有如下内容:对象
1.术语
(1)"promise"是一个对象或者函数,该对象或者函数有一个then方法
(2)"thenable"是一个对象或者函数,用来定义then方法
(3)"value"是promise状态成功时的值
(4)"reason"是promise状态失败时的值
咱们明确术语的目的,是为了在本身实现promise时,保持代码的规范性原型
2.要求
(1)一个promise必须有3个状态,pending,fulfilled(resolved),rejected。
当处于pending状态的时候,能够转移到fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,就不可变。
promise英文译为承诺,也就是说promise的状态一旦发生改变,就永远是不可逆的。it
(2)一个promise必须有一个then方法,then方法接受两个参数:
promise1.then(onFulfilled, onRejected);
其中onFulfilled方法表示状态从pending —> fulfilled(resolved)时所执行的方法,而onRejected表示状态从pending —> rejected所执行的方法。
(3)为了实现链式调用,then方法必须返回一个promise
promise2 = promise1.then(onFulfilled, onRejected);
了解了Promise/A+规范以后,下面咱们来看如何实现一个Promise。
首先构造一个myPromise函数,关于全部变量和函数名,应该与规范中保持相同。
function myPromise(constructor) { let self = this; self.status = 'pending'; self.value = undefined; // 成功时的值 self.reason = undefined; // 失败时的值 function resolve (value) { // 1.确保状态只能由 pending 改成 resolved if (self.status === 'pending') { self.value = value; self.status = 'resolved'; } } function reject (reason) { // 2.确保状态只能由 pending 改成 rejected if (self.status === 'pending') { self.reason = reason; self.status = 'rejected'; } } try { constructor(resolve, reject); } catch(e) { reject(e); } }
同时,须要在myPromise的原型上定义链式调用的then方法:
myPromise.prototype.then = function (onFullfilled, onRejected) { let self = this; switch (self.status) { case 'resolved': onFullfilled(self.value); break; case 'rejected': onRejected(self.reason); break; } };
上述就是一个初始版本的myPromise,在myPromise里发生状态改变,而后在相应的then方法里面根据不一样的状态能够执行不一样的操做。
let mp = new myPromise(function (resolve, reject) { resolve(1); // reject('err msg'); }); mp.then(function (res) { console.log(res); }, function (err) { console.log(err); }); // 输出 1
可是这里myPromise没法处理异步的resolve。好比:
let mp1 = new myPromise(function (resolve, reject) { setTimeout(() => { resolve(2); }, 2000); }); mp1.then(function (res) { console.log(res); }); // 无输出
...