Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺和重复的AJAX调用_Javascript_Jquery_Ajax_Promise - Fatal编程技术网

Javascript 承诺和重复的AJAX调用

Javascript 承诺和重复的AJAX调用,javascript,jquery,ajax,promise,Javascript,Jquery,Ajax,Promise,我正在尝试提出一个函数,其签名将与jQuery.ajax相同。它是一个单独的函数,因为根据响应中的HTTP状态,它应该完成并解析返回的承诺,或者发出具有相同参数的延迟的后续AJAX请求(因此重复)。虽然我有一个可行的解决方案,但我觉得这是一个承诺反模式,因为我显式地调用$.Deferred()来表示流程的状态。问题: 是否可以重用$.ajax调用返回的“thenable”对象,就像链接后续调用返回的承诺一样 每次调用另一个$.ajax时,您将如何在承诺链上合并一个progress调用 请参考

我正在尝试提出一个函数,其签名将与
jQuery.ajax
相同。它是一个单独的函数,因为根据响应中的HTTP状态,它应该完成并解析返回的承诺,或者发出具有相同参数的延迟的后续AJAX请求(因此重复)。虽然我有一个可行的解决方案,但我觉得这是一个承诺反模式,因为我显式地调用
$.Deferred()
来表示流程的状态。问题:

  • 是否可以重用
    $.ajax
    调用返回的“thenable”对象,就像链接后续调用返回的承诺一样
  • 每次调用另一个
    $.ajax
    时,您将如何在承诺链上合并一个
    progress
    调用
请参考我拥有的功能:

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();
};
是否可以重用$.ajax调用返回的“thenable”对象,就像链接后续调用返回的承诺一样

是和否。您将丢失多个参数,并且无法发出进度事件。它看起来是这样的:

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();
}
每次调用另一个$.ajax时,您将如何在承诺链上合并一个进度调用

只要打电话:


我真的很喜欢你用额外的
tryit
closure给它的触感,我不太喜欢“检查我是否已经有了延迟”的解决方案。我猜如果你使用eg.Q或when.js,链接后续承诺的限制仍然存在?你不能调用
progress
?我不太了解他们的progression API,但我猜你需要一个延迟的API。使用链接,我可以想到类似
。然后(函数(数据){…返回新承诺(函数(res,rej,prog){prog(“重试”);res()}。延迟(2000)。然后(tryit);…})
但不确定这样做是否会更好…
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();
}