【发布时间】:2020-11-30 13:28:05
【问题描述】:
过去两周我学习了以下内容: setImmediate、process.nextTick、setTimeout、promise、回调、libuv、事件循环、作业/微任务队列、事件循环队列、调用堆栈等。
我真的掉进了一个无法逃脱的兔子洞,虽然我发现自己更了解情况,但我仍然难以掌握 JavaScript 中的异步代码。
我想了解以下基本场景并了解如何异步实现它:
// does nothing; here to simulate functionality below
var data = new Array(10000000);
const displayTime = desc => {
var time = new Date();
console.log(
("0" + time.getHours()).slice(-2) + ":" +
("0" + time.getMinutes()).slice(-2) + ":" +
("0" + time.getSeconds()).slice(-2) + " " + desc
);
}
displayTime('starting ...');
// --- async/await (a promise):
const processData = async(data) => {
let dataLen = data.length;
let processedData = [];
//console.time('#1');
for (let ctr = 0; ctr < dataLen; ctr++) {
// something happens here; simulating a long task using a for-loop;
// for purposes of this question, let's just assume it's necessary to do this
processedData.push(ctr / 33 * 383739722);
}
//console.timeEnd('#1');
return processedData;
}
(async() => {
result = await processData(data);
// console.log(result);
displayTime('#1 completed ...');
})();
// --- promise:
const processData2 = data => {
return new Promise((resolve, reject) => {
let dataLen = data.length;
let processedData = [];
//console.time('#2');
for (let ctr = 0; ctr < dataLen; ctr++) {
processedData.push(ctr / 33 * 383739722);
}
//console.timeEnd('#2');
resolve(processedData)
});
}
processData2(data).then(data => {
// console.log(data);
displayTime('#2 completed ...');
});
displayTime('end of program ...');
输出是:
18:09:48 starting ...
18:09:52 end of program ...
18:09:52 #1 completed ...
18:09:52 #2 completed ...
从输出中可以看出,“程序结束...”直到两个长时间运行的进程完成后才回显到屏幕上(见时间)。
为什么?
我怎样才能在后台运行这两个任务(它们都使用承诺),以便它们不会立即阻塞事件循环和我的“程序结束...”字符串回显?
【问题讨论】:
-
声明函数
async不会使其异步运行。它只是返回 promise 的语法糖,这使得使用 if 它执行异步代码变得更容易,并允许它在内部使用await来调用其他异步函数。 -
打电话给
setTimeout。 -
setTimeout异步执行其回调函数。 -
当我运行您的代码 sn-p 时,我只会收到
starting消息和错误屏幕。你抄对了吗? -
@Barmar 似乎 Gary 有一些同步处理,他正试图异步执行,即以非阻塞方式。在这种情况下,唯一的选择是工作线程。
标签: javascript node.js