我有很多文章, 通过文章标题的表格列表可视地指示, 我们必须执行特定的处理操作, 一个接一个地处理物品, 通过发送带有该文章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中工作正常,逐个处理项目,从表格列表中删除相应的行。
但是在谷歌浏览器中,所有这些似乎都是一次性处理的,而不是在另一个完成后发生的这些请求。
经过一些谷歌搜索,发现引用说使用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);
疑惑:
答案 0 :(得分:0)
您建议的递归解决方案有效且有意义,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());
}
请注意,在此示例中,promises中包含的返回值将被丢弃,并且仅保留最后一个值。如果需要,可以修改它以捕获和聚合所有返回值。
将其提取为可重用的内容也很容易。例如:
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承诺兼容的承诺,但这是您应该检查并注意的事项。