如何在TypeScript中链接递归Ajax加载promise

时间:2014-07-17 13:54:52

标签: jquery ajax typescript promise

我正在努力成为一名优秀的jQuery公民,并接受承诺,但一些基本用法仍然让我感到厌烦。

下面的代码是一种面板加载方法,它可能会收到重定向到另一个页面的请求,而不是加载指定的原始页面。重定向受到严格控制(例如,基于先前的用户响应)。

private _loadNewPanel(url: string, data?: any): JQueryPromise<any>
{
    var THIS = this;
    var dfd = $.Deferred();
    var promise = dfd.promise();

    $.ajax({
        cache: false,
        url: url,
        type: data ? "POST" : "GET",
        data: data
    })
        .done((html: string, textStatus: string, jqXHR: JQueryXHR) =>
        {
            var location = jqXHR.getResponseHeader('redirect-url');
            // Server says to redirect
            if (location)
            {
                // Chain to the new load request
       // **** WHAT TO DO HERE WITH RETURNED PROMISE ***
                THIS._loadNewPanel(location, null);
            }
            else
            {
                dfd.resolve(html);
            }
        }).fail((jqXHR, textStatus: string, errorThrown: string) =>
        {
            dfd.reject(errorThrown + ": " + url);
        });

    return promise;
}

是否只是简单地将.done()添加到这样的递归调用并传回结果?

       // Chain to the new load request
       THIS._loadNewPanel(location, null).done(function(html){
             dfd.resolve(html);
       }).fail(function(error: string){
             dfd.reject(error);
       });

是否有更时尚的写作方式?我是否滥用jQuery承诺?

1 个答案:

答案 0 :(得分:1)

是的,有一种更为流畅的方式来写整篇文章。 $.ajax已经使用了承诺。

为了使用它返回的承诺,只需返回它:

 THIS._loadNewPanel(location, null).done(function(html){
         dfd.resolve(html);
 }).fail(function(error: string){
         dfd.reject(error);
 });

可以简单地说:

 return THIS._loadNewPanel(location, null); // why is THIS uppercase here :P? 

同样在上面的代码中。您只需要API的绝对最低级别的延迟,并且只有在API首先不支持错误时才需要。实际上你所做的就是the deferred anti pattern

如果要链接回复,可以使用.then

var req = $.ajax({...}).then(function(resp){
      var location = req.getResponseHeader("redirect-url");
      if(location) return THIS._loadNewPanel(location, null); // NOTE THE RETURN
      return resp;
});
return req;