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中的处理方式:
- 使用callback
- 回复一个承诺 。
以前我总是使用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()