JavaScript Promise 实现(一)

大家在进行前端开发的时候,想必都经常会接触到 Promise 对象类型,这在使用或基于 jQuery、Node.js 和 ES6 等的开发过程中会经常见到。Promise 对象通常被用来设定延迟和异步的计算,例如,当一个 AJAX 请求提出后,返回一个 Promise 对象,我们可以在这个对象里追增接下来要做到事情,而这些事情其实会等到这个 AJAX 请求结束后才会被执行,而非立即。所以,Promise 通常在具有以下特性的场景中使用。

  • 我们预期一个操作会有结果,但由于这个操作本身需要耗费一定的时间,因此该操作在当下可能并未完成。
  • 当该操作完成并成功时,会有通知,并可能会附带有运算结果。
  • 当该操作失败时,会有通知,并可能会附带有出错信息。
  • 当操作完成后,无论成功与否,都不会再重新返回到原先的运行中或其它任何状态。

在 ES6 中,我们可以按照以下方式使用。

var promise = new Promise(
    function (resolve, reject) {
        // 主要业务逻辑。
        setTimeout(function () {
            // 主要业务逻辑里的回调。
            var now = new Date();
            if (now.getSeconds() % 2 === 0)
                // 切换为成功状态,并触发回调。
                resolve(now);
            else
                // 切换为失败状态,并触发回调。
                reject(now);
        }, 1000);
    });
 
// 注册回调。
promise.then(
    function (value) {
        // 成功时的回调。
        console.debug("Success", value);
    },
    function (reasone) {
        // 失败时的回调。
        console.debug("Error", reasone);
    });

这段代码,会创建一个 Promise 对象,并注册了一组回调(可以注册多组),以分别在其成功和失败时会触发指定的事件。而在 Promise 对象内注册的业务逻辑,则只是简单地制定在一秒钟后根据当前时间状况,确定是进入成功或失败的逻辑分支,并将结果或出错信息做为参数返回,触发刚才提及的那些回调。具体说来,当运行这段代码时,会按照以下步骤进行。

  1. 首先,创建了一个 Promise 对象,里面的传入参数是一个函数,做为该 Promise 的主要业务逻辑。
  2. 执行该传入函数,并为该函数传入两个参数,分别是成功和失败时的触发器。
  3. 对 Promise 执行结束后的事件注册。可以注册多组事件,每组包括一个成功和一个失败,也可以是成功或失败的一个。这些事件组将按照先后顺序执行。
  4. 主要业务逻辑的异步回调此时可能被执行到。
  5. 主要业务逻辑可能会将当前状态切换为成功或失败,由此会自动调用该类注册的事件。
  6. 在调用成功或失败的事件时,会按照注册的顺序来执行。如果在执行成功事件时发生错误,会调用对应的失败事件(如果有)。
  7. 如果成功或失败时间中有返回值,则会自动创建下一个 Promise 对象,以便将延迟异步过程和对应的结果逐个传递下去。

说了这么多,我要开始研究如何实现该类了。

既然说到这是一个类,那么,考虑到前面说的需求,我们先来看看其应该具备哪些方法和属性,以及看看构造函数是怎样的。

  • 首先,需要一个构造函数,我们需要传入一个函数,即所需的主要业务逻辑,该函数可能是个运算量较大或等待时间较长的函数。该函数需要支持两个参数,分别是成功和失败时的触发器。每个触发器其实又是一个函数,并可接受可选的运算结果或出错信息。
  • 其次,还需要一个成员方法,用于注册成功和失败的回调。该方法需要提供两个参数,即成功后的回调,和失败后的回调。这些回调当然也都是方法啦,并支持传入可选的参数,这些参数其实就是成功时的运算结果或失败时的出错信息。同时,这些回调也可以返回结果,这个结果将被用于自动生成下一个 Promise 对象,供之后继续传递。

于是乎,我们得到以下代码。为了便于从基本说明,以下代码均使用 ES5 书写。

var Promise = function (executor) {
    // ToDo: Implement it.
};
Promise.prototype.then = function (onfulfilled, onrejected) {
    return Promise(function (resolve, reject) {
        // ToDo: Implement it.
    });
};
Promise.prototype.catch(onrejected) {
    return this.then(null, onrejected);
}

显然,我们还需要一些变量或字段来存储一些的信息。

  • 状态信息,如进行中、成功、失败。
  • 成功时的运算结果或失败时的出错信息。

因此,我们需要现在构造函数中初始化状态信息。

this._state = null;

该值为布尔值,当为 true 时表示成功,false 时为失败,默认为 null 表示运行中。而成功或失败后的结果,我们后面预计使用 this._value 来存储。

现在,我们已经大致拟定好了一个接口,接下来的实现,且看后续文章。

【未完待续】

文章类型及复杂度:Web 前端开发进阶。

节选翻译自 MSDN 博文 JavaScript Promise,内容有所调整。

http://blogs.msdn.com/b/kingcean/archive/2016/03/25/promise-in-web.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值