异步JavaScript - 回调与延迟/承诺

Ben*_*ter 51 javascript commonjs jquery-deferred

可能重复:
Javascript中Deferred,Promise和Future之间有什么区别?

最近我一直在努力提高我的JavaScript应用程序的质量.

我采用的一种模式是使用单独的"数据上下文"对象来为我的应用程序加载数据(之前我在我的视图模型中直接执行此操作).

以下示例返回在客户端上初始化的数据:

var mockData = (function($, undefined) {

    var fruit = [
        "apple",
        "orange",
        "banana",
        "pear"
        ];

    var getFruit = function() {
        return fruit;
    };

    return {
        getFruit: getFruit
    }
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,我们将从服务器加载数据,因此我们无法立即返回响应.在我们的API中,我似乎有两种选择:

  1. 使用回调
  2. 回复承诺.

以前我总是使用回调方法:

var getFruit = function(onFruitReady) {
    onFruitReady(fruit);
};

// ...

var FruitModel = function(dataContext, $) {
    return {
        render: function() {
            dataContext.getFruit(function(fruit) {
                // do something with fruit
            });
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

但是,我可以看到如何最终回调地狱,特别是在构建复杂的JavaScript应用程序时.

然后我遇到了Promises的设计模式.我不是要求调用者提供回调,而是返回一个可以观察到的"承诺":

var getFruit = function() {
    return $.Deferred().resolve(fruit).promise();
};

// ...
dataContext.getFruit().then(function(fruit) {
    // do something with fruit
});
Run Code Online (Sandbox Code Playgroud)

我可以看到使用这种模式的明显好处,特别是因为我可以wait使用多个延迟对象,这在加载单个页面应用程序的初始化数据时非常有用.

但是,在我开始使用愤怒之前,我很想了解每种模式的优缺点.我也对这是否是其他库的方向感兴趣.似乎是jQuery的情况.

这是我用于测试的小提琴的链接.

Chr*_*phe 18

Promise也依赖于场景背后的回调,所以它并不是真正的一对一.

回调的好处是它们很容易用纯JavaScript实现(例如在ajax调用中).

Promise需要一个额外的抽象层,这通常意味着你将依赖于一个库(因为你已经在使用jQuery,所以不是你的问题).当您并行处理多个异步调用时,它们是完美的.

  • 请注意,截至2014年3月,浏览器已开始实现本机承诺,因此我的声明仅适用于polyfill. (9认同)