javascript - 将 then 方法添加到回调函数

标签 javascript callback

我最近看到一些代码是这样的:

myFunc(args).then(function() { ... });

我发现这个回调语法非常优雅。我的理解是这不是 vanilla JS 的一部分,我希望能够在不依赖特定库的情况下偶尔使用它,所以我对如何自己实现它很感兴趣。那么,这种东西是如何工作的,您将如何为函数调用实现它?

最佳答案

这种模式称为“ promise ”。它由 jQuery 和 dojo 等实现,一种方法是查看它们的代码并了解它们是如何实现的。

一般的实现模式是创建一个函数,该函数返回一个对象,该对象包含一个函数(然后)将一对函数作为回调传递给先前的方法,该方法将在成功或失败时运行。 MSDN 在 blog post here 中有更多关于 promise 的信息

在 gitHub 上发布了一个极简主义的实现:Promises GIST

function Promise () {
    this._thens = [];
}

Promise.prototype = {

    /* This is the "front end" API. */

    // then(onResolve, onReject): Code waiting for this promise uses the
    // then() method to be notified when the promise is complete. There
    // are two completion callbacks: onReject and onResolve. A more
    // robust promise implementation will also have an onProgress handler.
    then: function (onResolve, onReject) {
        // capture calls to then()
        this._thens.push({ resolve: onResolve, reject: onReject });
    },

    // Some promise implementations also have a cancel() front end API that
    // calls all of the onReject() callbacks (aka a "cancelable promise").
    // cancel: function (reason) {},

    /* This is the "back end" API. */

    // resolve(resolvedValue): The resolve() method is called when a promise
    // is resolved (duh). The resolved value (if any) is passed by the resolver
    // to this method. All waiting onResolve callbacks are called
    // and any future ones are, too, each being passed the resolved value.
    resolve: function (val) { this._complete('resolve', val); },

    // reject(exception): The reject() method is called when a promise cannot
    // be resolved. Typically, you'd pass an exception as the single parameter,
    // but any other argument, including none at all, is acceptable.
    // All waiting and all future onReject callbacks are called when reject()
    // is called and are passed the exception parameter.
    reject: function (ex) { this._complete('reject', ex); },

    // Some promises may have a progress handler. The back end API to signal a
    // progress "event" has a single parameter. The contents of this parameter
    // could be just about anything and is specific to your implementation.
    // progress: function (data) {},

    /* "Private" methods. */

    _complete: function (which, arg) {
        // switch over to sync then()
        this.then = which === 'resolve' ?
            function (resolve, reject) { resolve(arg); } :
            function (resolve, reject) { reject(arg); };
        // disallow multiple calls to resolve or reject
        this.resolve = this.reject = 
            function () { throw new Error('Promise already completed.'); };
        // complete all waiting (async) then()s
        var aThen, i = 0;
        while (aThen = this._thens[i++]) { aThen[which] && aThen[which](arg); }
        delete this._thens;
    }

};

(请注意,这不是我的代码。我仔细查看了它,它作为一个起点看起来不错,但所有功劳归于 original author )

关于javascript - 将 then 方法添加到回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14793830/

相关文章:

javascript - 根据属性值删除对象数组中的重复项

javascript - 尝试使用 nsIPrefBranch 在 Firefox 扩展上存储数据会给出 NS_ERROR_UNEXPECTED

javascript - 如何调试打不开的页面(空白页)

javascript - Google/Typekit Webfont-Loader 不检测非 ASCII 字体

javascript - Meteor/Node.js : Multiple http requests within a for loop, 在时间间隔内均匀分布?

在函数完成之前触发 Javascript 回调(无 jQuery)

javascript - 在某些窗口宽度下呈现 Google Chrome 中的错误

javascript - 为带有文件夹的网站制作通用的页眉和页脚

python - 回调与基于生成器的设计

javascript - 展平嵌套回调