Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.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/jQuery AJAX POST请求,在请求数据数组上循环?_Javascript_Jquery - Fatal编程技术网

如何使用承诺顺序发送Javascript/jQuery AJAX POST请求,在请求数据数组上循环?

如何使用承诺顺序发送Javascript/jQuery AJAX POST请求,在请求数据数组上循环?,javascript,jquery,Javascript,Jquery,我有一大堆文章, 通过文章标题列表直观显示, 我们必须对其执行特定的处理操作, 一个接一个地处理项目, 通过发送带有该文章id的POST请求, 从表列表中删除该行时,将其作为进度的可视指示器 这是我最初使用的: var article_ids = [1,2,...]; article_ids.each(function (value, index) { var id = value; jQuery.ajax({ type: "POST", url: "index.php?

我有一大堆文章, 通过文章标题列表直观显示, 我们必须对其执行特定的处理操作, 一个接一个地处理项目, 通过发送带有该文章id的POST请求, 从表列表中删除该行时,将其作为进度的可视指示器

这是我最初使用的:

var article_ids = [1,2,...];
article_ids.each(function (value, index) {
  var id = value;
  jQuery.ajax({
    type: "POST",
    url: "index.php?process_article",
    data: {article_id: id},
    cache: false,
    async: false
  })
  .done(function(reponse) {
    console.log(response);
    jQuery('.article-id-' + id).css('display', 'none');
  });  
});
它在FireFox中运行良好,一个接一个地处理项目,从表列表中删除相应的行

但在谷歌Chrome中,所有这些似乎都是一次性处理的,而不是一个接一个的请求

在谷歌搜索了一段时间后,我发现了一些关于使用Javascript承诺的参考资料,但我不知道如何在这种情况下使用

然后,我将上述内容改为以下递归函数,它似乎在Chrome和Firefox上都能正常工作,请求一个接一个地发生:

var article_ids = [1,2,...];
function processIds(ids) {
  if (ids.length > 0) {
    id = ids.shift();     
    console.log("Processing ID: " + id);
    jQuery.ajax({
      type: "POST",
      url: "index.php?process_article",
      data: {article_id: id},
      cache: false
    })
    .done(function() {
      jQuery('.article-id-' + id).css('display', 'none');
      processIds(ids);
    });
  } else {
    alert("Successfully processed all articles.");
  }
}
processIds(article_ids);
怀疑:

  • 这是个好办法吗
  • 我们如何使用Javascript承诺实现同样的目标

  • 在我看来,您建议的递归解决方案很有效,也很有意义。在这种情况下,我通常使用
    Array.reduce

    下面是一个例子:

    function processIds(ids) {
      return ids.reduce((promise, nextId) => {
        return promise.then(() =>
          jQuery.ajax({
            type: "POST",
            url: "index.php?process_article",
            data: { article_id: nextId },
            cache: false,
          })
        );
      }, Promise.resolve());
    }
    
    请注意,在本例中,承诺中包含的返回值被丢弃,只保留最后一个值。如果需要的话,可以修改它来捕获和聚合所有返回值

    将其提取为可重用的内容也很容易。例如:

    function forEachAsync(myArray, funcPromise) {
      return myArray.reduce((promise, nextValue) => {
        return promise.then(() => funcPromise(nextValue));
      }, Promise.resolve());
    }
    
    然后您可以使用新的
    forEachAsync
    函数,如下所示:

    function processIds(ids) {
      return forEachAsync(ids, processArticle);
    }
    
    function processArticle(id) {
      return jQuery.ajax({
        type: "POST",
        url: "index.php?process_article",
        data: { article_id: nextId },
        cache: false,
      });
    }
    
    我相信jQuery的最新版本使用与JavaScript承诺兼容的承诺,但这是您应该检查和注意的


    我相信它们是在中引入的,jQuery在中引入了兼容性。

    A
    promise
    可能会让您有同样的行为。@AjAX.,谢谢!用承诺写这篇文章的好方法是什么?我的意思是,在Chrome中,你可能会再次得到所有的东西。我认为你可以像以前那样少编写代码。
    ajax
    调用还返回一个
    promise
    。成功后,您可以从列表中调用相同的函数。默认情况下,ajax是
    async
    ,不会等待下一个进程。它将开始处理数组中的下一项。因此,您可以在
    success
    上调用相同的函数。@AjAX.,上面显示的递归函数,在Chrome中似乎工作得很好,每个请求都在前一个请求完成后发生。虽然我仍然不知道如何使用promise来写这个。非常感谢,伙计,这正是我想要的!非常感谢。完成。非常感谢。谢谢你美丽的回答!:-)