承诺和经常性的AJAX调用 [英] Promises and recurrent AJAX calls

查看:180
本文介绍了承诺和经常性的AJAX调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拿出他的签名会和 jQuery.ajax 函数。它是一个独立的功能,因为这取决于在响应中的HTTP状态它应该要么完全和解决的承诺归还,或发出延迟后续的AJAX请求以相同的参数(因此复发)。虽然我有一个解决方案,工程,我觉得这是一个承诺反模式,因为我显式调用 $。递延()来重新present状态的过程。问题:

  • 是可以重复使用的<​​code> $。AJAX返回的thenable对象通话,如链接起来的后续调用返回的承诺?
  • 你将如何去整合一个每一次进步都对诺链调用另一个 $。阿贾克斯被称为?

请参见功能我有:

  callAPI =功能(jqAjaxOptions,延迟){
  如果(延迟== NULL){
    递延= $ .Deferred();
  }
  $阿贾克斯(jqAjaxOptions)。总是(功能(数据,状态,XHR){
    变参;
    的args = _.toArray(参数);
    开关(xhr.status){
      案例200:
        返回deferred.resolve.apply(延迟,参数);
      案例201:
      案例202:
        返回的setTimeout(函数(){
          返回callAPI(jqAjaxOptions,延期);
        },2000);
      默认:
        deferred.reject.apply(延迟,参数);
        如果(data.responseText){
          返回app.notifier.set(JSON.parse(data.responseText));
        } 其他 {
          返回app.notifier.set({
            标题:无法联系数据服务器。
            内容:看来API服务器已关闭,请联系DAV球队。
          });
        }
    }
  });
  返回deferred.promise();
};
 

解决方案
  

是否有可能重新使用的$就调用返回的thenable对象,如链接起来的后续调用返回的承诺?

是和否您就输定了多个参数,而且也没有办法发出进度事件。它是这样的:

 函数超时(毫秒){
    变种D = $ .Deferred();
    的setTimeout(d.resolve,MS);
    返回d.promise();
}
功能callApi(ajaxOptions){
    功能tryit(){
        返回$阿贾克斯(ajaxOptions)。然后(数据){
             如果(this.status == 200)
                 返回的数据;
             否则,如果(this.status == 201 || this.status == 202)
                 返回超时(2000)。然后(tryit);
             其他
                 返回$ .Deferred()。拒绝(this.responseText
                   ? JSON.parse(this.responseText)
                   :{
                     标题:无法联系数据服务器。
                     内容:看来API服务器已关闭,请联系DAV球队。
                 });
        });
    }
    返回tryit();
}
 

  

你会如何去了解每个另一个$就被调用时引入一个正在进行的呼叫的诺言链?

只需拨打 通知

 函数callApi(ajaxOptions){
    VAR推迟= $ .Deferred();
    功能tryit(){
        $阿贾克斯(jqAjaxOptions)。总是(函数(){
            开关(this.status){
                案例200:
                    返回deferred.resolveWith(这一点,参数);
                案例201:
                案例202:
                    deferred.notify(下一个尝试2S);
                    返回的setTimeout(tryit,2000年);
                默认:
                    deferred.notify(this.responseText
                      ? JSON.parse(this.responseText);
                      :{
                            标题:无法联系数据服务器。
                            内容:看来API服务器已关闭,请联系DAV球队。
                    });
                    deferred.rejectWith(这一点,参数);
            }
        });
    }
    尝试一下();
    返回deferred.promise();
}
 

I am trying to come up with a function whose signature would be identical to jQuery.ajax. It is a separate function because depending on the HTTP status in the response it should either complete and resolve the promise returned, or issue a delayed subsequent AJAX request with identical parameters (hence the recurrence). While I have a solution that works, I feel like it's a promise anti-pattern, because I am explicitly calling $.Deferred() to represent the state of the process. Questions:

  • is it possible to reuse the „thenable" object returned by the $.ajax calls, as in chaining up the promises returned by subsequent calls?
  • how would you go about incorporating a progress call on the promise chain each time another $.ajax is called?

Please refer to the function I have:

callAPI = function(jqAjaxOptions, deferred) {
  if (deferred == null) {
    deferred = $.Deferred();
  }
  $.ajax(jqAjaxOptions).always(function(data, status, xhr) {
    var args;
    args = _.toArray(arguments);
    switch (xhr.status) {
      case 200:
        return deferred.resolve.apply(deferred, args);
      case 201:
      case 202:
        return setTimeout(function() {
          return callAPI(jqAjaxOptions, deferred);
        }, 2000);
      default:
        deferred.reject.apply(deferred, args);
        if (data.responseText) {
          return app.notifier.set(JSON.parse(data.responseText));
        } else {
          return app.notifier.set({
            title: "Couldn't contact data server.",
            content: "It seems the API server is down. Please contact the DAV team."
          });
        }
    }
  });
  return deferred.promise();
};

解决方案

Is it possible to reuse the „thenable" object returned by the $.ajax calls, as in chaining up the promises returned by subsequent calls?

Yes and No. You would loose the multiple arguments, and there's no way to emit progress events. It would look like this:

function timeout(ms) {
    var d = $.Deferred();
    setTimeout(d.resolve, ms);
    return d.promise();
}
function callApi(ajaxOptions) {
    function tryit () {
        return $.ajax(ajaxOptions).then(data) {
             if (this.status == 200)
                 return data;
             else if (this.status == 201 || this.status == 202)
                 return timeout(2000).then(tryit);
             else
                 return $.Deferred().reject(this.responseText
                   ? JSON.parse(this.responseText)
                   : {
                     title: "Couldn't contact data server.",
                     content: "It seems the API server is down. Please contact the DAV team."
                 });
        });
    }
    return tryit();
}

How would you go about incorporating a progress call on the promise chain each time another $.ajax is called?

Just call notify:

function callApi(ajaxOptions) {
    var deferred = $.Deferred();
    function tryit() {
        $.ajax(jqAjaxOptions).always(function() {
            switch (this.status) {
                case 200:
                    return deferred.resolveWith(this, arguments);
                case 201:
                case 202:
                    deferred.notify("Next try in 2s");
                    return setTimeout(tryit, 2000);
                default:
                    deferred.notify(this.responseText
                      ? JSON.parse(this.responseText);
                      : {
                            title: "Couldn't contact data server.",
                            content: "It seems the API server is down. Please contact the DAV team."
                    });
                    deferred.rejectWith(this, arguments);
            }
        });
    }
    tryit();
    return deferred.promise();
}

这篇关于承诺和经常性的AJAX调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆