如何转换jQuery $.ajax调用蓝鸟承诺没有延迟的反模式
How to cast jQuery $.ajax calls to Bluebird promises without the deferred anit-pattern
现在我在核心文件中使用promise.deferred。这使我能够在一个中心位置解决承诺。我一直在阅读我可能正在使用反模式的文章,我想了解为什么它不好。
所以在我的core.js文件中我有这样的函数:var getMyLocation = function(location) {
var promiseResolver = Promise.defer();
$.get('some/rest/api/' + location)
.then(function(reponse) {
promiseResolver.resolve(response);
)}
.catch(function(error) {
promiseResolver.reject(error);
});
return promiseResolver.promise;
}
然后在我的getLocation.js文件中有以下内容:
var core = require('core');
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something with data
}).catch(throw error);
在阅读了Bluebird文档和许多关于延迟反模式的博客文章之后,我想知道这个模式是否实用。我可以将其更改为以下内容:
core.js
var getMyLocation = function(location) {
var jqXHR = $.get('some/rest/api/' + location);
return Promise.resolve(jqXHR)
.catch(TimeoutError, CancellationError, function(e) {
jqXHR.abort();
// Don't swallow it
throw e;
});
getLocation.js
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something
})
.catch(function(error) {
throw new Error();
});
我想我很困惑,什么是最好的方法有一个中央库处理xhr请求使用jquery调用,但蓝鸟的承诺。
你可以在jQuery中调用Promise.resolve
并让Bluebird吸收它:
var res = Promise.resolve($.get(...)); // res is a bluebird Promise
你也可以直接在Bluebird链中返回jQuery承诺,并让它吸收它。
myBluebirdApi().then(function(){
return $.get(...);
}).then(function(result){
// The jQuery thenable was assimilated
});
你下面的代码很接近,但你不需要捕捉TimeoutError
,因为jQuery ajax不会抛出这些。至于捕获取消错误。如果您希望取消请求,无论如何,这是您正在做的最佳实践。
要将thenable转换为Bluebird promise,您可以使用can调用Promise.resolve
,如下所示:
var promise = Promise.resolve($.getJSON(...));
奖金部分:
大多数JQuery AJAX函数都是启用的,但是对于你的信息,如果你想转换一个函数,期望一个回调到一个承诺,你可以使用Promise.fromNode
。按照Node.js世界的惯例,将使用参数err, result
调用回调:
var promise = Promise.fromNode(function (callback) { request(url, callback); });
如果回调的第一个参数不存在潜在的错误,你可以解决这个问题:
var promise = Promise.fromNode(function (callback) {
FB.api(url, function(response) { callback(response ? response.error : "no response", response); });
});