批量发送API调用

时间:2019-01-25 05:24:03

标签: javascript node.js

我目前正在尝试模拟50万个IoT设备,以使用Node.js将负载推送到Azure IoT中心。由于节点本质上是多线程的,因此其节点集线器充斥着数据,并且我遇到了网络错误。

我也尝试了async / await方法,但这花了很多时间将数据推送到IoT中心。

是否有一种方法只能并行运行100个呼叫,等待所有呼叫完成,然后再运行节点中的下100个?

非常感谢!

4 个答案:

答案 0 :(得分:2)

将批处理构建为Promise的嵌套数组,然后使用Promise.all 在每个批次中,每个Promise.all都需要await来解决。

const sendRequest = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('request sent')
      resolve()
    }, 1000)
  })
}

// 5 batches * 2 requests = 10 requests.
const batches = Array(5).fill(Array(2).fill(sendRequest))

;(async function() {
  for (const batch of batches) {
    try {
      console.log('-- sending batch --')
      await Promise.all(batch.map(f => f()))  
    } catch(err) {
      console.error(err)
    }
  }
})()

答案 1 :(得分:1)

您可以随时将bluebird Promise's map与并发选项一起使用。这将处理并发中提到的最大记录,然后再提取下一批。 示例:

Promise.map([], {concurrency : 100})

答案 2 :(得分:1)

// My dummy ImageWrapper public class ImageWrapper { public string Val { get; set; } } public partial class MainWindow { private CallbackRestriction _restriction = new CallbackRestriction(); public MainWindow() { InitializeComponent(); _restriction.AddCallback(MyCallback, new ImageWrapper() {Val = "Hello"}); Task.Run(_restriction.CallbackEmitLoop); } private void MyCallback(ImageWrapper wrapper) { // since the callback will be running on the // thread associated with the task, if you // want to interact with the UI in the callback // you need to use Dispatcher Dispatcher.BeginInvoke(new Action(() => { Debug.WriteLine(wrapper.Val); })); } } 可用于将请求排队。有一些选项可以设置任何给定时间的最大连接数。下面是我们每秒发送5个请求的代码。在任何给定时间也只会发送5个请求。

limited-request-queue

limited-request-queue

答案 3 :(得分:0)

如果您正在使用 lodash,您可以使用 chunk 使它更容易一些,它将数组划分为提供的最大大小的块

所以在你的情况下你可以这样使用它

变量调用(可以说是 550 个数组)

const batchCalls = _.chunk(calls, 100);

for (const batchCall of batchCalls) {
  await Promise.all(batchCall.map(call => call())) // makes a hundred calls in series
}