Javascript 承诺功能(I/O)阻止反应UI
我需要一个函数通过Javascript 承诺功能(I/O)阻止反应UI,javascript,node.js,reactjs,redux,electron,Javascript,Node.js,Reactjs,Redux,Electron,我需要一个函数通过dgram发送大量数据,由于某种原因,这目前正在阻止我的UI。 在我的React组件中,我有一个按钮: <button onClick={() => { foo(); }} > Run foo </button>; bar在我的网络服务中定义: export const bar = () => { return new Promise((resolve, reject) => { baz()
dgram
发送大量数据,由于某种原因,这目前正在阻止我的UI。
在我的React组件中,我有一个按钮:
<button
onClick={() => {
foo();
}}
>
Run foo
</button>;
bar
在我的网络服务中定义:
export const bar = () => {
return new Promise((resolve, reject) => {
baz()
.then((result) => {
console.log(result);
resolve();
})
.catch(() => {
console.error("Something went wrong with baz!");
reject();
});
});
};
和baz
,执行实际I/O的功能(“hello”用于调试):
在本例中,我通过它的回调函数使用crypto.randomBytes,hello 3是我得到的最后一个打印。这意味着回调甚至不起作用。正如代码中所评论的,我可以同步获取随机字节,但它仍然会阻塞UI。
在其他语言中,我会为baz创建一个新线程来运行,但据我所知,I/O应该在节点中异步工作。
欢迎您的回复 无关注释:您只应使用承诺构造函数(“新承诺”)将“回调样式”转换为“承诺样式”。这是一个非常普遍的误解
baz()
已经是一个承诺resolve()
和reject()
只应调用一次(reject()
缺少返回,而resolve()
位于映射内,将被多次调用)
export const bar = () => {
return new Promise((resolve, reject) => {
baz()
.then((result) => {
console.log(result);
resolve();
})
.catch(() => {
console.error("Something went wrong with baz!");
reject();
});
});
};
const baz = () => {
return new Promise((resolve, reject) => {
const targets = ReduxStore.getState().targetReducer.targets;
console.log("hello1, with targets:", targets);
// Return if no targets
if (targets.lenght === 0) return;
const crypto = require("crypto");
const dgram = require("dgram");
const client = dgram.createSocket("udp4");
console.log("hello2");
while (ReduxStore.getState().targetReducer.attackActive) {
const port = ReduxStore.getState().targetReducer.port;
console.log("hello3, port:", port);
/* const randomBytes = crypto.randomBytes(1024); */
// The above randomBytes is synchronous and works, but still blocks UI.
// The below is async and does not even run!
crypto.randomBytes(1024, (err, buf) => {
if (err) {
reject(err);
}
console.log("hello4");
targets.map((target, i) => {
client.send(buf, port, target, (err, responseBytes) => {
console.log("Response from", target, ":", responseBytes);
if (err) {
reject(err);
}
});
client.close();
resolve(`Sent 1024 bytes to ${target} on port ${port}.`);
});
});
}
});
};