什么是Promise?
Promise可以简单理解为一个事物,这个事物存在三种状态:
- 已经完成了 resolved
- 因为某种原因被中断了 rejected
- 还在等待上一个事务结束 pending
Promise 就是一个事务的管理器。他的作用就是将各种内嵌回调的事务用流水形式表达,其目的是为了简化编程,让代码逻辑更加清晰。

Promise是一个构造函数,自身有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法,用Promise new出来的对象肯定就有then、catch方法了
var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('执行完成'); resolve('123'); }, 2000); });
Promise的构造函数接收一个参数,是函数,这个函数接收两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。resolve是将Promise的状态置为resolved,reject是将Promise的状态置为rejected。
在上面的代码中,我们执行了一个异步操作,也就是setTimeout,2秒后,输出“执行完成”,并且调用resolve方法。
运行代码,会在2秒后输出“执行完成”。注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数:
function runAsync(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('执行完成'); resolve('123'); }, 2000); }); return p; } runAsync()
在操作事务之前,我们会先把各种事务依次放入事务队列中,这里会用到 then 方法:
Promise.prototype.then = function (nextAffair){ var promise = new Promise(); if (this.state == ‘resloved’){ // 如果当前状态是已完成,则这个事务将会被立即执行 return this._fire(promise, nextAffair); }else{ // 否则将会被加入队列中 return this._push(promise, nextAffair); } };
如果整个操作已经完成了,那 then 方法送进的事务会被立即执行,
Promise.prototype._fire = function (nextPromise, nextAffair){ var nextResult = nextAffair(this.result); if (nextResult instanceof Promise){ nextResult.then(function(obj){ nextPromise.resolve(obj); }); }else{ nextPromise.resolve(nextResult); } return nextPromise; };
被立即执行之后会返回一个结果,这个结果会被传递到下一个事务中作为原料,但是这里需要考虑两种情况:
- 异步,如果这个结果也是一个 Promise,则需要等待这个 Promise 执行完毕再将最终的结果传到下一个事务中。
- 同步,如果这个结果不是 Promise,则直接将结果传递给下一个事务。
第一种情况还是比较常见的,比如我们在一个事务中有一个子事务队列需要处理,此时必须等待子事务完成才能回到主事务队列中。
Promise.prototype.resolve = function (obj){ if (this.state != ‘pending’) { throw ‘流程已完成,不能再次开启流程!’; } this.state = ‘resloved’; // 执行该事务,并将执行结果寄存到 Promise this.result = this.affair(obj); for (var i = 0, len = this.allAffairs.length; i < len; ++i){ // 往后执行事务 var affair = this.allAffairs[i]; this._fire(affair.promise, affair.affair); } return this; };
resolve 接受一个参数,这个数据是交给第一个事务来处理的,因为第一个事务的启动可能需要数据,它也可以是空。该事物处理完毕之后,将操作结果(result)寄存在 Promise 对象上,方便引用,然后将结果(result)作为原料送入下一个事务。
我们看到 then 方法中还调用了一个 _push ,这个方法的作用是将事务推进事务管理器(Promise)。
Promise.prototype._push = function (nextPromise, nextAffair){ this.allAffairs.push({ promise: nextPromise, affair: nextAffair }); return nextPromise; };
以上操作,我们就实现了一个简单的事务管理器