运行以下javascript代码时,它可以正常工作。但是如果你删除了setTimeout函数调用并用一行代码替换它,如:
resolve(x);
浏览器将挂起。
浏览器似乎挂起,因为它正在处理无限循环中对processNode函数的调用。但是,目前还不清楚为什么会发生阻塞。 processNode返回一个Promise。此外,startNodeProcessing是一个异步函数,它在调用时使用await。我认为通过使用等待的Promise和async函数可以防止任何阻塞线程,但显然我错了。似乎setTimeout只是在一个单独的线程上执行其代码,从而阻止了阻塞。但如果是这种情况,为什么还要使用Promise或async函数来开始?
function processNode(x) {
return new Promise(resolve => {
console.log("X: " + x + " " + Date.now());
setTimeout(() => {
resolve(x);
}, x);
});
}
async function startNodeProcessing() {
while(true) {
var a = processNode(1);
var b = processNode(1);
var c = processNode(1);
var d = processNode(1);
var a1 = await a;
var b1 = await b;
var c1 = await c;
var d1 = await d;
}
return;
}
startNodeProcessing();
答案 0 :(得分:1)
以下情况发生了:
var a = processNode(1);
//the parser jumps to processNode and creates a promise:
return new Promise(function(resolve)
//the promise is resolved
resolve(x);
//the function returns, we enter the main function again:
var a1 = await a;
//await internally calls the then function:
a1.then(return to this func)
//as the promise is resolved, the then callback is called immeadiately
//the parser returns to the main function
正如您所看到的,解析器永远不会退出循环,因此它会阻塞,因为它永远不会停止。
答案 1 :(得分:0)
此外,startNodeProcessing是一个异步函数 在电话上使用等待。
不,await
未在通话中使用。调用是在await
之前的行进行的。见serial await requests in a return run in parallel?
它在没有setTimeout的情况下阻塞。只需将setTimeout替换为 resolve(x)它会阻塞。我试图了解原因。
因为立即调用了Promise
构造函数executor
函数,所以立即调用Question中console.log()
构造函数中的Promise
,无论是否或何时{{1函数参数被调用。
resolve
语法
Promise(resolve => { console.log("this is not executed asynchrously"); resolve(1) })
参数
执行
使用参数resolve和reject传递的函数。该 执行函数由Promise立即执行 实现,传递解析和拒绝功能(执行者是 在Promise构造函数之前调用甚至返回创建的 对象)。