如何在承诺主体中创建自己的异步工作?

时间:2019-01-04 17:36:46

标签: javascript asynchronous promise async-await

我编写了模仿大型工作的函数。我需要获取输出:

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()函数,是否可以得到相同的输出?

3 个答案:

答案 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循环时在 期间阻塞执行:它只是以特定的顺序发生,即“工作”被推迟到当前执行堆栈变空为止。