日期:2014-05-16  浏览次数:20367 次

JavaScript 中的异步梳理(2)——使用 Promises/A

接上篇,这篇探讨使用 CommonJS Promises/A 来管理异步操作。

写在前面:本人并没有系统深入研究过 Promises 模型,但以解决问题为目的进行了一些尝试,本文更多围绕自己的理解写,而非规范本身。

Promises?是一种异步编程模型,通过一组 API 来规范化异步操作,这样也能够让异步操作的流程控制更加容易。

这里谈的是?Promises/A,算是 Promises 的一个分支吧,其实就是根据 Promises 模型定义了一组 API。 由于 Promises 对于新手而言理解曲线还是比较陡峭的,这里循序渐进的给大家介绍,同时实现一个最简单的 Promises/A 代码。

Promises/A 有个别名叫做「thenable」,就是「可以 then」的。 这里一个 promise 有三种状态:[默认、完成、失败],初始创建的时候是默认状态,状态只可以从默认变成完成,或者默认变成失败。 一旦完成或者失败,状态就不能再变。 为了简化文章,这里我们先只考虑完成,不考虑失败。

var Promise = function(ok){
    this.state = 'unfulfilled';
    this.ok =  || function(obj) { return obj; };
};
Promise.prototype = {
    resolve: function(obj){
        if (this.state !== 'unfulfilled') throw '已完成,不能再次resolve';
        this.state = 'fulfilled';
    }
};
var promise = new Promise(function(obj){ return obj; });

构造函数中的 ok 是一个任务,promise.resolve(obj)?表示将该?promise?的状态改为完成, 此时 ok 会被执行,其返回值作为后续操作的参数以及?resolve?的返回值。

由于没有和任何异步操作关联在一起,这里的 Promise 还没有任何作用。 Promises/A 之所以叫「thenable」是因为它的核心 API 叫做 then,望文生义这个方法的作用是当一个 promise 完成或失败后继续干别的事情。

  • then 传入一个函数作为参数 nextOK①,当该 promise 被 resolve 时,resolve 的返回值将会传递到 nextOK 中。

  • then 返回一个 promise,当上述后续操作完成时,返回的 promise 也会被 resolve。

  • 如果 promise 的状态是已完成,则 nextOK 会被立即调用。

但是这样并无法异步,因此这里有一个特殊情况,就是如果 nextOK 的返回值也是一个 Promise, 那么 then 返回的 promise 需要当这个 promise 被 resolve