自学内容网 自学内容网

【JavaScript】JavaScript同步任务、异步任务(宏任务和微任务)

JavaScript同步任务、异步任务

  • 同步任务: 当前主线程将要消化执行的任务,这些任务一起形成执行栈。
  • 异步任务: 不进入主线程,而是进入任务队列,即不会马上进行的任务。

任务队列的异步任务又分为宏任务与微任务,也就是说宏任务和微任务虽然都是异步任务,都在任务队列中,但是它们在不同的队列中。

一般情况下,宏任务包含以下内容:script,setTimeout setInterval, I/O, 事件,postMessage,setImmediate, requestAnimationFrame, UI渲染。

微任务包含以下内容: Promise.then, MutationObserver, process.nextTick

示例:

console.log('start here');

setTimeout(() => {
    console.log('setTimeout');
}, 0);

new Promise((resolve, reject) => {
    resolve('promise result');
}).then(value => {
    console.log(value);
});

console.log('end here');

输出结果:

start here // 同步任务
end here // 同步任务
promise result // 微任务
setTimeout // 宏任务

可以看出是先执行同步任务,然后执行微任务,然后执行宏任务。但是由于先执行script,浏览器会先执行一个宏任务,再执行同步任务,如果有异步代码的话才会先执行微任务。

Promise里的代码为什么比setTimeout先执行实例

Promise和setTimeout实例

我们把宿主发起的任务称为宏观任务,把 JavaScript 引擎发起的任务称为微观任务。许多的微观任务的队列组成了宏观任务。

为了理解微任务始终先于宏任务,我们设计一个实验:执行一个耗时 1 秒的 Promise。

setTimeout(()=> console.log('d'),0);
var r = new Promise(function(resolve,reject){
    resolve();
});

r.then(() => {
    var begin = Date.now();
    while(Date.now() - begin < 1000);
    console.log("c1");
    
    new Promise(function(resolve,reject){
        resolve();
    }).then(() => console.log("c2"));
    
})

// 结果:c1 c2 d

这里我们强制了 1 秒的执行耗时,这样,我们可以确保任务 c2 是在 d 之后被添加到任务队列。

我们可以看到,即使耗时一秒的 c1 执行完毕,再 enque 的 c2,仍然先于 d 执行了,这很好地解释了微任务优先的原理。

再看一个复杂点的例子:

function sleep(duration) {
    return new Promise(function(resolve, reject) {
        console.log("b");
        setTimeout(resolve,duration);
    })
}
console.log("a");
sleep(5000).then(()=>console.log("c"));

//a b c

这是一段非常常用的封装方法,利用 Promise 把 setTimeout 封装成可以用于异步的函数。

我们首先来看,setTimeout 把整个代码分割成了 2 个宏观任务,这里不论是 5 秒还是 0 秒,都是一样的。

第一个宏观任务中,包含了先后同步执行的 console.log(“a”); 和 console.log(“b”);。

setTimeout 后,第二个宏观任务执行调用了 resolve,然后 then 中的代码异步得到执行,所以调用了 console.log(“c”),最终输出的顺序才是: a b c。

Promise 是 JavaScript 中的一个定义,但是实际编写代码时,我们可以发现,它似乎并不比回调的方式书写更简单,但是从 ES6 开始,我们有了 async/await,这个语法改进跟 Promise 配合,能够有效地改善代码结构。


原文地址:https://blog.csdn.net/mengran_code/article/details/142775961

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!