asynchronousJavaScript – callbackvs延期/承诺

可能重复:
JavaScript中的延期,承诺和未来有什么区别?

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

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

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

var mockData = (function($, undefined) { var fruit = [ "apple", "orange", "banana", "pear" ]; var getFruit = function() { return fruit; }; return { getFruit: getFruit } })(jQuery); 

在大多数情况下,我们将从服务器加载数据,所以我们不能立即返回响应。 看来我有两个select来处理我们在API中的处理方式:

  1. 使用callback
  2. 回复一个承诺 。

以前我总是使用callback方法:

 var getFruit = function(onFruitReady) { onFruitReady(fruit); }; // ... var FruitModel = function(dataContext, $) { return { render: function() { dataContext.getFruit(function(fruit) { // do something with fruit }); } }; }; 

不过,我可以看到如何才能最终回到地狱,特别是在构build复杂的JavaScript应用程序时。

然后我遇到了Promisesdevise模式。 而不是要求调用者提供callback,而是返回一个可以观察到的“承诺”:

 var getFruit = function() { return $.Deferred().resolve(fruit).promise(); }; // ... dataContext.getFruit().then(function(fruit) { // do something with fruit }); 

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

不过,在开始使用愤怒之前,我很想了解每种模式的优缺点。 我也感兴趣的是这是否是其他图书馆正在进行的方向。jQuery似乎是这种情况。

这里是我用来testing的小提琴的链接 。

承诺也依赖于幕后的callback,所以它不是一个和另一个。

callback的好处是它们很容易用普通的JavaScript实现(例如在Ajax调用中)。

承诺需要一个额外的抽象层,这通常意味着你将依赖一个库(在你的情况下不是一个问题,因为你已经使用jQuery)。 当你并行处理多个asynchronous调用时,它们是完美的。

通过阅读@Pointy链接到的jQuery文档 ,听起来不同的是,Deferred API允许您指定在请求完成时调用多个函数:

从jQuery 1.5开始,错误(失败),成功(完成)和完成(总是,从jQuery 1.6开始)callback钩子是先进先出的pipe理队列。 这意味着您可以为每个钩子分配多个callback。 请参阅Deferred对象方法,它们在内部为这些$ .ajax()callback钩子实现。

另请参阅: deferred.then()