【问题标题】:Extending done() in jQuery's Promise object在 jQuery 的 Promise 对象中扩展 done()
【发布时间】:2015-06-03 14:52:44
【问题描述】:

我想将$.ajax().done() 包装在一个单独的类中,其中包括针对模式验证 JSON 响应。

示例调用可能如下所示:

myService.get("/api/people").done(function(people) {
    // at this point I'm certain the data in people is valid
    template.render(people);
}).catch(function() {
    // this happens if validation of people failed, even if the request itself was successfull
    console.log("empty json or validation failed");
});

成功回调函数在done() 中传递,但仅应在私有函数(_validate(data, schema)) 返回 true 时执行。不太优雅的版本可能如下所示:

myService.get("api/people", successCallback, errorCallback);

我想直接暴露$.ajax()的内部Deferred方法。这可能吗?

【问题讨论】:

  • 您有一个GET,它可能会返回无效数据?我错过了什么吗?这听起来很疯狂。
  • @Mathletics 这一点都不疯狂。 在野外 请求将随机失败。例如,您将只获得身体的一部分,您可能会从服务器获得 404 或 500,或者您可能会失去连接。
  • myService.get("api/people").then(successCallback, errorCallback); ???
  • @Mathletics JSON 请求本身可能成功,但我想根据一组标准验证响应对象。
  • @Halcyon 但任何一种情况都是请求错误,并会触发相应的处理程序。 OP 表示请求将成功,但实际响应可能包含无效数据(不是损坏/坏数据,只是不适合客户端某些架构的数据。)

标签: javascript jquery ajax promise jquery-deferred


【解决方案1】:

您无需更改Promises。你可以使用then layer promises。

function _validate(data, schema) {
    return false;
}

var myService = {
    get: function (data) {
        return $.ajax(data).then(function (reply) {
            if (_validate(reply, schema)) {
                return reply;
            } else {
                // works if your library is Promises/A+ compliant (jQuery is not)
                throw new Error("data is not valid JSON"); // causes the promise to fail
                /*// else do:
                var d = new $.Deferred();
                d.reject("data is not valid JSON");
                return d.promise();*/
            }
        });
    }
}

myService.get("foo").done(function () { /* success */ }).fail(function () { /*failed */ });

【讨论】:

  • 当您在 return 中添加 then 时,这将成为新结果。这允许您修改结果(如管道和过滤器)或使承诺失败(通过抛出错误)。
  • 好吧,我很高兴知道这一点
  • 不会在返回的 JSON 上调用 .done() 导致错误吗?
  • @Halcyon:啊,不符合 Promises/A+ 的实现的乐趣……是的,与大多数 Promise 库不同,jQuery 不会捕获 .then 中抛出的错误。
  • @A.Wolff 我知道我确实犯了一个可能导致混淆的错误。我有 return d; 而不是 return d.promise(); 我认为 jQuery 有一些魔力,如果需要 Promise,它会将 Deferred 转换为其关联的 Promise。啊 jQuery .. 你为什么要这样?对我来说太神奇了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2017-07-29
  • 2012-10-28
相关资源
最近更新 更多