我目前正在尝试模拟50万个IoT设备,以使用Node.js将负载推送到Azure IoT中心。由于节点本质上是多线程的,因此其节点集线器充斥着数据,并且我遇到了网络错误。
我也尝试了async / await方法,但这花了很多时间将数据推送到IoT中心。
是否有一种方法只能并行运行100个呼叫,等待所有呼叫完成,然后再运行节点中的下100个?
非常感谢!
答案 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
答案 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
}