当前位置: 首页 > 知识库问答 >
问题:

JavaScript:同步执行一系列promise

苗康平
2023-03-14

我有一个需要在循环中执行的请求promise,比如:

var ids = [1,2,3];
doPromise(1).then(function(){
  doPromise(2).then(function(){
    doPromise(3);
  }
})

问题是我永远不知道数组中有多少元素,所以我需要一个动态模式。有没有可能混合同步和异步世界,以便在一个时刻只有一个请求是活动的(序列不重要)?

共有1个答案

干高歌
2023-03-14

依次迭代数组的一种经典方法是,在每个数组元素上调用一些异步操作,方法是使用。减少()并链接到一个初始promise,如下所示:

问题是我永远不知道数组中有多少元素,所以我需要一个动态模式。

您可以使用promise链将它们逐个排序。为此,使用.reduce()迭代数组非常有用,因为它提供了正确的迭代类型,可以在迭代数组时跟踪累积值(在本例中是一个promise)。您可以使用额外的变量使几乎任何数组迭代方案工作,这与.reduce()

var ids = [1,2,3,4,5,6,7];
ids.reduce(function(p, item) {
    return p.then(function() {
        return doPromise(item);
    });
}, Promise.resolve()).then(function(results) {
    // all done here with array of results
});

这会将已解析的promise传递给作为promise链头的ids.reduce()。然后,它对该promise执行.Then(),并为数组中的每个项返回一个新promise(通过.reduce()回调)。.reduce()调用的最终结果将是一个promise,解决后意味着整个链都完成了。

理解这一点的关键是要记住,p.then()返回一个新的promise,所以我们只是继续调用。然后()对每个新promise,我们从每个中的每个操作返回promise。然后()处理程序。这具有将所有promise链接到一个顺序链中的效果。

是否可以混合使用同步和异步世界,以便一个时刻只有一个请求处于活动状态(顺序不重要)?

我不知道你说的“混合同步和异步世界”是什么意思。确保一次只有一个请求在运行的方法是将它们依次排列,以便下一个请求仅在前一个请求完成时启动。这也恰好保证了执行顺序,尽管您说这在本例中并不重要,但这是确保一次只执行一个的副产品。

下面是一个工作片段:

function log(msg) {
    var d = document.createElement("div");
    d.textContent = msg;
    document.body.appendChild(d);
}

function doPromise(x) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            log(x);
            resolve(x);
        }, Math.floor(Math.random() * 1000));
    });
}

var ids = [1,2,3,4,5,6,7];
ids.reduce(function(p, item) {
    return p.then(function() {
        return doPromise(item);
    });
}, Promise.resolve()).then(function() {
    // all done here
    log("all done");
});
 类似资料:
  • 我有一个promise对象数组,这些对象必须按照数组中列出的顺序进行解析,也就是说,在解析前一个元素之前,我们不能尝试解析元素(正如方法所做的那样)。 如果一个元素被拒绝,我需要链立即拒绝,而不试图解析下面的元素。 我如何实现这一点,或者对于这样的模式是否存在现有的实现? 编辑 最初的答案表明,我们只能这些数组元素的结果,而不是它们的执行,因为它在这样的例子中是预定义的。 那么,如何以避免提前执行

  • 问题内容: 我需要在 node.js 函数中 它将 同步 执行给定的命令行并返回该命令文本的所有标准输出。 ps。同步是错误的。我知道。仅供个人使用。 更新 现在我们有了mgutz的解决方案,该解决方案为我们提供了退出代码,但没有stdout!仍在等待更准确的答案。 问题答案: Node.js(从0.12版本开始-已有一段时间)支持: 您现在可以直接执行以下操作: 它会做您期望的。(默认将I /O

  • 一旦遇到这样的问题,这里还有更多内容,然后发现了 一个适当恶劣的解决方法。 这篇文章没有列在索引中,但是为满足你的好奇心而保留了下来。

  • 我正在建立一个网站使用Node.js和序列(与Postgres后端)。我有一个用外键返回许多对象的查询,我想向视图传递一个外键引用的对象列表。 在本例中,Attentings包含Hackathon键,我想返回Hackathon的列表。由于代码是异步的,以下内容在节点中当然不起作用: 有没有办法以同步的方式进行查询,这意味着我直到“黑客”列表充满所有对象才返回视图? 谢谢!

  • 问题内容: 我的任务是按以下顺序创建线程:如果A开始->启动B和C,如果B开始->启动D。并以相反的顺序销毁它们如果D然后B。如果B和C然后A。它。我设法做到了,但我想还有更好的方法。你有什么建议吗? 在您发表评论后,我更改了代码,这非常简单。但是现在看起来“愚蠢”。我想更改if语句和实现的硬性,有什么建议吗?寻求建议,我正在与您一起学习。 这是我的新代码: 问题答案: 您的代码中存在一些缺陷,这

  • 目前生产出现了,handleDealData()返回的结果是[],并非是forEach执行后的数组,此问题偶发。 但是查了资料,解释说forEach的循环是同步任务。 chrome测试正常,返回非[] forEach的执行顺序是否跟机型、浏览器有关?