大家好,我正在尝试构建一个ReactJS应用,该应用可控制和监视某些物理设备的状态。为了获取这些物理设备的状态,我使用的请求如下所示:
+toplevel.js
此请求需要发送到多个设备(9-10点附近)。但是其中有些将被关闭,有些可能不会回答,那么避免等待此请求超时并通过多线程方法合并它们的最大方法是什么?谢谢!
答案 0 :(得分:1)
对于JS中的“并发性”,请使用Promise.all()
。
查看https://hackernoon.com/concurrency-control-in-promises-with-bluebird-977249520f23了解更多信息。
根据需要编辑以下代码,但这里有一个粗略的轮廓
// assuming these are your devices
const devices = [1,2,3,4,5,6,7,8,9]
// These were then passed to Promise.all() to be executed in parallel.
let opvObj = {};
await Promise.all(devices.map(async (device)=>{
axios.get('http://192.168.1.***:8080')
.then( response => {
let deviceStatusMode = 0;
if(response.data.isCritical) {
deviceStatusMode = 1;
} else if (response.data.isWarning) {
deviceStatusMode = 2;
} else {
deviceStatusMode = 3;
}
// build up opvObj
opvObj[`odv${device}`] = deviceStatusMode;
})
.catch(error => {
// do something with the error
console.log(error)
});
}));
//dispatch
store.dispatch(odvStatus(opvObj));
答案 1 :(得分:0)
javascript中没有真正的多线程概念-所有执行都在单个线程上进行。但是,由于javascript具有异步事件循环,因此我们仍然可以互操作代码的不同部分,而不必等待任何http请求完成。
由于看起来您正在使用redux,因此您所要做的就是保留与现在相同的代码,除了您应该以增量方式更新状态(即,仅使用“ odv1”而不是“ odv1”-“ odv3” ”。再次查看redux reducer文档以了解操作方法。
然后,您可以彼此立即进行多个axios.get
调用。由于javascript的异步特性,它们不会互相阻塞(即,http请求将同时在运行中,而不是严格按顺序执行):
axios.get('/dev1').then(...);
axios.get('/dev2').then(...);
axios.get('/dev3').then(...);
axios.get('/dev4').then(...);
axios.get('/dev5').then(...);
有关更多信息,请查看有关js event loop的详细信息。
如果您确实需要执行一些与主gui线程分开的操作(即,如果您具有10,000+个设备状态,则需要每秒更新一次),则可以签出web workers。但是,根据您共享的内容,我认为这将带来比项目所需的复杂性更多的功能。
编辑:
以上答案之一提出了Promise.all
。尽管我喜欢他将核心逻辑提取到其自身功能中的方法,但使用Promise.all
只是将所有的诺言组合为一个。这仍将导致您必须等到最慢的设备响应后才能更新商店,这几乎绝对不是您想要的。同样,在http请求返回时对redux存储执行增量更新几乎绝对肯定是将最新信息显示到用户屏幕上的最快方法。