簡體   English   中英

如何使用Promises順序發送Javascript / jQuery AJAX POST請求,遍歷請求數據數組?

[英]How to send Javascript/jQuery AJAX POST requests sequentially, looping over an array of request data, using Promises?

我有大量的文章列表,以列表形式直觀地顯示了文章標題,我們必須對其執行特定的處理操作,通過發送帶有該文章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中可以正常工作,一個接一個地處理項目,並從表列表中刪除相應的行。

但是,在Google Chrome瀏覽器中,所有這些似乎都是一次性處理的,而不是這些請求中的一個在另一個完成之后發生。

經過一番谷歌搜索,發現引用說使用Javascript Promises,我不知道如何在這種情況下使用。

然后,我改為將上面的內容更改為以下遞歸函數,該函數似乎在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);

疑問:

  1. 這是解決這個問題的好方法嗎?
  2. 我們如何使用Javascript Promises實現相同的目標?

您建議的遞歸解決方案行之有效,IMO。 在這種情況下,我通常使用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承諾兼容,但這是您應該檢查並注意的事項。

我相信它們是在ES2015中引入的,而jQuery在v3.0中引入了兼容性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM