返回已解决的承诺

我有一个现有的项目,它有很多异步函数,可以返回承诺。我正在添加一些缓存,以便在某些情况下异步函数将同步完成,并希望尽可能缩短/改进此代码:

返回$.Deferred(函数(def){def.resolve();}).promise();

例如,我有一个数据服务类,它处理大多数AJAX请求,如下所示:

函数数据服务(){
var self=这个;
self.makeRequest=函数(函数名、数据){
return$.Deferred(函数(def)){
var jsonData=JSON.stringify(数据);
$.ajax({
类型:“POST”,
url:“WebService.asmx/”+functionName,
资料来源:jsonData,
contentType:“应用程序/json;字符集=utf-8”,
数据类型:“json”,
错误:函数(xhr、状态、错误){
var-ex;
试一试{
ex=评估(“+xhr.responseText+”);
ex.message=ex.message;
例如,消息=未定义;
}捕获(ex2){
ex={message:“来自服务器的响应无效:\r\n”+xhr.responseText};
}
如果(例如消息==“需要登录”){
app.viewModels.main.loginRequired(true);
}
否则{
应用程序淋浴错误(例如信息);
}
定义拒绝(例如消息);
}
});
}).promise();
}
}

然后我在另一个类中有一个函数,它当前总是调用makeRequest:

self.deleteMe=function()
{
返回app.dataservice.makeRequest('deleteItem');
}

我想更新deleteMe函数,这样它就不会总是调用makeRequest,而是执行一些同步工作,然后返回。不过,它需要返回一个承诺,因为不管它叫什么,它都会期待,但它需要是一个“已经完成/解决的承诺”。目前我正在使用上面的第一组代码来实现这一点。看来一定有更好的办法

@埃塞尔克

根据我的经验,$.Deferred(函数(def){…})构造很少需要,尽管我想它在某些情况下非常有用

首先:

返回$.Deferred(函数(def){def.resolve();}).promise();

将简化为:

返回$.Deferred().resolve().promise();

其次,在DataService.makeRequest()中,您可以通过利用.then()来避免显式$.Deferred,如下所示:

函数数据服务(){
var self=这个;
self.makeRequest=函数(函数名、数据){
返回$.ajax({
类型:“POST”,
url:“WebService.asmx/”+functionName,
数据:JSON.stringify(数据),
contentType:“应用程序/json;字符集=utf-8”,
数据类型:“json”
}).then(null,函数(xhr,状态,错误){
var-ex;
试一试{
ex=评估(“+xhr.responseText+”);
ex.message=ex.message;
例如,消息=未定义;
}捕获(ex2){
ex={
消息:“来自服务器的响应无效:\r\n”+xhr.responseText
};
}
如果(例如消息==“需要登录”){
app.viewModels.main.loginRequired(true);
}否则{
应用程序淋浴错误(例如信息);
}
返回例如消息;
});
};
}

这里的关键方面是:

  • $.ajax()返回与promise兼容的jqXHR对象,该对象(在成功/错误时)立即由执行并修改。然后()
  • .then(null,…)-导致传递一个新的承诺,并使用与$.ajax()返回的原始承诺相同的值进行解析。因此,在“完成”(即ajax成功)条件下,.then()是完全透明的
  • 返回exmessage-导致传递新承诺,并以ex.message拒绝

虽然,IMHO,链接.then()比在$.Deferred()回调中设置所有内容要干净得多,但是nett效果应该与原始代码相同

顺便说一句,通过设置适当的HTTP头服务器端,“.Message”直接显示为失败回调的status参数(或xhr.status),您可以避免使用eval(“+xhr.responseText+”)等。例如,在PHP中,您可以执行以下操作:

$message=“我的自定义邮件”;
标题(“HTTP/1.1421$message”);
出口(0);

我相信ASP提供了同样的功能

IIRC,任何4xx系列状态代码都可以完成此任务。421只是碰巧是一个没有特定意义的人

发表评论