我编写了模仿大型工作的函数。我需要获取输出:
Work started.
Hello!
Work done.
Bob
这是我的“ Hello World”示例:
function bigWork(user){
console.log('Work started.');
const p = new Promise(resolve => {
setTimeout(() => {
// here is some long calculatin must
// be done async. Therefore I placed
// it inside of setTimeout() function
for(let n = 0; n < 100000; n++);
console.log('Work done.');
resolve(user);
},0);
});
return p;
}
bigWork({name:'Bob', age:30}).then(user=> console.log(user.name));
console.log('Hello!');
其输出与我预期的相同。但是我被迫使用setTimeout()
函数。我故意使用setTimeout()
函数来获取所需的控制台输出。
如果不使用setTimeout()
函数,是否可以得到相同的输出?
答案 0 :(得分:1)
很抱歉将其破解给您,但是JavaScript从技术上讲是单线程的。
它似乎对您有用的原因是setTimeout代码仅在主“线程”完成后才发生,因此,在循环阻塞javascript时,示例应用程序并没有真正表明它正在发生。
您可以做的是使用WebWorkers,它将实现您想要的多线程,但它本身就是一个野兽。 https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
答案 1 :(得分:0)
据我了解,您想要以下内容。
async function bigWork(user){
console.log('Work started.');
const p = await longCalculation(100, user);
console.log('Work done.');
return p;
}
function longCalculation(round, user){
return new Promise((resolve) => {
for(let n = 0; n < round; n++);
resolve (user);
})
}
bigWork({name:'Bob', age:30}).then(user=> console.log(user.name));
console.log('Hello!');
答案 2 :(得分:-1)
您可以使用Promise.resolve
:
function bigWork(user){
console.log('Work started.');
return Promise.resolve().then(() => {
for(let n = 0; n < 100000; n++);
console.log('Work done.');
return user;
});
}
bigWork({name:'Bob', age:30}).then(user=> console.log(user.name));
console.log('Hello!');
请注意,尽管这可以确保您想要的顺序,但并不能防止在执行for
循环时在 期间阻塞执行:它只是以特定的顺序发生,即“工作”被推迟到当前执行堆栈变空为止。