如何从Ajax内部报告额外的拒绝承诺

时间:2014-06-20 15:12:58

标签: jquery typescript promise

我正在寻找解决这种情况的最佳方法。我需要对返回的Ajax数据进行额外检查,这可能导致我的_loadPanel承诺操作“失败”:

_loadPanel(url: string, data?: any) : JQueryPromise<any>
{
    return $.ajax(
        {
            url: url,
            type: data ? "POST" : "GET",
            data: data
        }).done(function (html: string, textStatus: string)
        {
             // Some function that exracts required data
             var $panel = extractPanelData(html);
             if (!$panel.length)
             {
                 // How to cause a reject here???
             }
        });
}

你不能这样做(下面),因为从Ajax返回的承诺是不可变的,无论如何它只是闻起来有点错误:

var promise = $.ajax({...}).done(function(...)
{ 
     promise.reject("Data failed promise");
});

是否有一种简单的方法可以不添加额外的$.Deferred()对象,或者这是唯一的模式?

尝试:

我已经尝试了以下内容,以便我可以修改父Deferred对象,但它不会编译:

var dfd = $.Deferred();
var promise = dfd.promise();
promise = promise.then($.ajax(
            {
                cache: false,
                url: url,
                type: data ? "POST" : "GET",
                data: data
            }).done(...));

这将允许我将Ajax承诺与Deferred承诺

结合起来

Supplied parameters do not match any signature of call target:Type '(value: {}) => {}' requires a call signature, but type 'JQueryXHR' lacks one.

建议?

很酷的东西:

不确定这是多么广为人知,并且它没有帮助解决这个问题(因为它也返回了一个不可变的承诺),但似乎你可以使用$.when传递初始参数到第一个功能

e.g。将初始参数传递给$.ajax,如下所示:

    $.when({
            url: url,
            type: data? "POST" : "GET",
            data: data
        }).then($.ajax).done(function (html: string, textStatus: string)

或单独的参数如下:

$.when("Hello!", 22, "There!")
    .then(insertPanel);

如果结果被链接到先前的promises ,这可能会带来有趣的好处,因为Ajax调用不会立即运行,而是仅在前面的步骤完成之后。

1 个答案:

答案 0 :(得分:0)

这里有一些问题:

  • .then连锁承诺并改变他们的状态。
  • .done不会链接承诺,但会为当前承诺添加处理程序并将其返回。

所以:

var xhr = $.ajax({...});
p = xhr.then(function(data){
    // fail if check fails
    if(additionalChecksFail) return $.Deferred.reject(Error("Invalid Request").promise(); 
    return data; // otherwise we maintain the same data
});

p.then(function(data){
   // will only run if data validation passed.
});