jquery – 返回已经解决的承诺

前端之家收集整理的这篇文章主要介绍了jquery – 返回已经解决的承诺前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个现有的项目,有很多异步函数返回promises。我添加一些缓存,以便在某些情况下,异步函数将完成同步,并希望尽可能使这个代码更短/更好:
return $.Deferred(function(def) { def.resolve(); }).promise();

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

function DataService() {

    var self = this;

    self.makeRequest = function(functionName,data) {
        return $.Deferred(function(def) {

            var jsonData = JSON.stringify(data);

            $.ajax({
                type: "POST",url: "WebService.asmx/" + functionName,data: jsonData,contentType: "application/json; charset=utf-8",dataType: "json",error: function(xhr,status,error) {
                    var ex;
                    try {
                        ex = eval("(" + xhr.responseText + ")");
                        ex.message = ex.Message;
                        ex.Message = undefined;
                    } catch (ex2) {
                        ex = { message: "Invalid Response From Server:\r\n" + xhr.responseText };
                    }
                    if (ex.message == "Loginrequired") {
                        app.viewmodels.main.loginrequired(true);
                    }
                    else {
                        app.showError(ex.message);
                    }
                    def.reject(ex.message);
                }
            });
        }).promise();
    }
}

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

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

我想更新deleteMe函数,以便它不总是调用makeRequest,而只是做一些同步工作,然后返回。它需要返回一个承诺,虽然,因为任何调用,它会期望,但它需要是一个“已经完成/已解决的承诺”。目前我使用第一组代码来做到这一点。似乎一定有一个更好的方法

解决方法

@Eselk,

在我的经验,$ .Deferred(function(def){…});建设很少需要,虽然我想在一些情况下可以是非常有用的。

首先, :

return $.Deferred(function(def) { def.resolve(); }).promise();

将简化为:

return $.Deferred().resolve().promise();

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

function DataService() {
    var self = this;
    self.makeRequest = function (functionName,data) {
        return $.ajax({
            type: "POST",data: JSON.stringify(data),dataType: "json"
        }).then(null,function (xhr,error) {
            var ex;
            try {
                ex = eval("(" + xhr.responseText + ")");
                ex.message = ex.Message;
                ex.Message = undefined;
            } catch (ex2) {
                ex = {
                    message: "Invalid Response From Server:\r\n" + xhr.responseText
                };
            }
            if (ex.message == "Loginrequired") {
                app.viewmodels.main.loginrequired(true);
            } else {
                app.showError(ex.message);
            }

            return ex.message;
        });
    };
}

这里的关键方面是:

> $ .ajax()返回一个promise兼容的jqXHR对象,它(成功/错误)被立即执行并被.then()修改
> .then(null,…) – 导致一个新的promise被传递,解析与$ .ajax()返回的原始promise相同的值。因此,在“完成”(即,ajax成功)条件下,.then()是完全透明的。
> return ex.message; – 导致一个新的promise被传递,被ex.message拒绝。

nett效果应该与你的原始代码相同,但是,IMHO,链.then()比在$ .Deferred()回调中设置一切显得更干净。

顺便说一下,你可以通过设置一个适当的HTTP头服务器端来避免eval(“(”xhr.responseText“)”)等的需要,使你的’.Message’直接出现作为状态参数xhr.status?)的失败回调。例如,在PHP中,您将执行以下操作:

$message = "my custom message";
header("HTTP/1.1 421 $message");
exit(0);

我相信ASP提供相同的功能

IIRC,任何4xx系列状态码都将完成这项工作。 421恰恰恰好是没有特定意义的一个。

猜你在找的jQuery相关文章