我有一个方法可以遍历JSON有效负载来对该有效负载中的一些数据运行计算.当我创建该方法的100个promise ,然后将它们传递给Promise.all()时,似乎同时解析的每个promise 都需要更长的时间才能解决下一个promise .

这并不是我的方法所特有的,我用一个返回简单JSON数据的公共APItry 了类似的方法.在使用Promise.all并发调用该API时,我观察到了相同的事情...每一个连续的promise 都需要越来越长的时间来解决.

下面是一个简单的代码片段来说明我正在做的事情:

const axios = require('axios');

const getSomeData = async () => {
  try {
    await axios.get('https://some.api.com');
  } catch (error) {
    console.log('Failed to get data...');
  }
};

const promiseList = [];

for (let i = 0; i < 100; i += 1) {
  promiseList.push(new Promise(async (res) => {
    const startTime = performance.now();
    await getSomeData();
    const stopTime = performance.now();
    console.log(`time taken by promise: ${stopTime - startTime}`);
    res();
  }));
}

const main = async () => {
  const startTime = performance.now();
  await Promise.all(promiseList);
  const stopTime = performance.now();
  console.log(`total time taken: ${stopTime - startTime}`);
};

main();

当然,这是一个非常没有意义的方法,但我创建它是为了严格观察并发运行时promise 的行为,以及与顺序运行相比有多大的性能优势(这显然是一个重大的改进).

我的问题是,是什么导致每一个连续的promise 都需要越来越长的时间,直到所有的promise 都得到解决?在这种情况下,如果我再次运行它,它会将第一个promise 所用的时间重置为大约200毫秒,然后它会再次开始增加,直到最后一个promise 需要大约600毫秒才能解决.

这仅仅是单线程Java执行和并发的本质吗?我真的很有兴趣听到对这一现象的更深入的解释.

推荐答案

Check the network waterfall: enter image description here

我猜您的API调用只是在后端被限制了.您的请求也在后端排队.

如果你用超时替换API调用,Promise.all就可以了:

const getSomeData = () => {
  try {
    return new Promise(r => setTimeout(r, 1000))
  } catch (error) {
    console.log('Failed to get data...');
  }
};

const promiseList = [];
const log = [];

for (let i = 0; i < 100; i += 1) {
  promiseList.push(new Promise(async (res) => {
    const startTime = performance.now();
    await getSomeData();
    const stopTime = performance.now();
    log.push(`time taken by promise: ${stopTime - startTime}`);
    res();
  }));
}

const main = async () => {
  const startTime = performance.now();
  await Promise.all(promiseList);
  const stopTime = performance.now();
  log.forEach(l => console.log(l));
  console.log(`total time taken: ${stopTime - startTime}`);
};

main();

Javascript相关问答推荐

按钮未放置在html dis位置

在React中获取数据后,如何避免不必要的组件闪现1秒?

Google图表时间轴—更改hAxis文本 colored颜色

如何找出摆线表面上y与x相交的地方?

为什么ngModel不能在最后一个版本的Angular 17上工作?'

使用JQuery单击元素从新弹出窗口获取值

并不是所有的iframe都被更换

S文本内容和值不必要的不同

使用原型判断对象是否为类的实例

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

当输入字段无效时,我的应用程序不会返回错误

在Reaction中的handleSubmit按钮内,useSelector值仍然为空

在使用REACT更改了CSS类之后,无法更改CSS样式

将对象推送到数组会导致复制

当从其他文件创建类实例时,为什么工作线程不工作?

输入的值的类型脚本array.排序()

如何在脚本编译后直接将RxJ模块导入浏览器(无需Angel、webpack、LiteServer)

谷歌饼图3D切片

有没有办法在R中创建一张具有多个色标的热图?

无法在Adyen自定义卡安全字段创建中使用自定义占位符