JavaScript运行机制.md

这篇博客详细探讨了JavaScript的运行机制,包括宏任务和微任务在主线程与异步任务中的执行顺序。文章强调了在循环宏任务中,只有当前轮宏任务执行完毕并检查到任务队列中有任务时,才会执行下一轮宏任务。同时,讲解了ES6的async/await如何通过Promise来控制异步流程,并提供了10道相关的JS运行机制练习题,帮助读者巩固理解。参考了相关博文以加深对Event Loop的解析。
  • 常见的一些宏任务(主线程)和微任务(异步任务)
macrotask 宏任务microtask微任务
setTimeoutprocess.nextTick
setIntervalPromises
setImmediateObject.observe
requestAnimationFrame-
I/O-
UI rendering-

JS运行机制

  • 循环宏任务的情况下, 每当当前轮宏任务执行完成询问任务队列是否存在任务, 存在执行, 不存在执行下一轮宏任务
    在这里插入图片描述
  • ES6—async + await
    async 的函数返回的都是 一个promise对象,也就是说,它会等待你在await的任务完成之后再继续宏任务
async function test() {
    await new Promise((res) => {
        console.log(1);
        res('成功');
    }).then(() => {
        console.log(2);
    })
    console.log(3);
}
test(); //1->2->3

JS运行机制练习题

题1
function test() {
    console.log(1);
    setTimeout(() => {
        console.log(2); //遇见setTimeout 放入下一轮宏任务循环中
    }, 1);
    [3, 4, 5].forEach((ele) => {
        new Promise(res => {
            res(ele);
        }).then(res => {
            console.log(res); //遇见.then(fn)放入异步线程执行
        })
   })
 }
 test(); //1->3,4,5->2
题2
function test() {
    console.log(1);
    setTimeout(() => {
        console.log(2); //遇见setTimeout 放入下一轮宏任务循环中
    }, 1);
    setTimeout(() => {
        console.log(55);
        [3, 4, 5].forEach((ele) => {
            new Promise((res) => {
                console.log(99);
                res(ele);
            }).then((res) => {
                console.log(res); //遇见.then(fn)放入异步线程执行
           });
       });
    }, 0);
   }
test(); //1->2->55->99,99,99->3,4,5
题3
async function test() {
    console.log(1);
    setTimeout(() => {
       console.log(2);
    }, 1);
    setTimeout(() => {
        console.log(666);
        [3, 4, 5].forEach((ele) => {
            new Promise((res) => {
                res(ele);
            }).then((res) => {
                console.log(res);
            });
       });
       console.log(6);
    }, 0);
    await new Promise((res) => {
        res(7);
    }).then((res) => {
        console.log(res);
    });
}
test(); //1->7->2->666->6->3,4,5
题4
console.log("1");
setTimeout(function() {
    console.log("2");
    process.nextTick(function() {
        console.log("3");
    });
    new Promise(function(resolve) {
        console.log("4");
        resolve();
    }).then(function() {
        console.log("5");
    });
});

process.nextTick(function() {
    console.log("6");
});

new Promise(function(resolve) {
    console.log("7");
    resolve();
}).then(function() {
    console.log("8");
});

setTimeout(function() {
    console.log("9");
    process.nextTick(function() {
        console.log("10");
    });
    new Promise(function(resolve) {
        console.log("11");
        resolve();
    }).then(function() {
        console.log("12");
    });
});
//同步任务  1-> 7
//微任务① nextTick  6-> ②then  8
//宏任务① setTimeout()  2-> 4->3->5

//宏任务② setTimeout() 9->11->10->12
//第一轮  1->7->6->8
题5
Promise.resolve().then(() => {
    console.log('1')
    setTimeout(() => {
        console.log('2')
    }, 0)
})

setTimeout(() => {
    console.log('3')
    Promise.resolve().then(() => {
        console.log('4')
    })
}, 0)

//1->3->2->4
题6
console.log(1)
setTimeout(function() {
    console.log(2);
    let promise = new Promise(function(resolve, reject) {
        console.log(7);
        resolve()
    }).then(function() {
        console.log(8)
    });
}, 1000);

setTimeout(function() {
    console.log(10);
    let promise = new Promise(function(resolve, reject) {
        console.log(11);
        resolve()
    }).then(function() {
        console.log(12)
    });
}, 0);

let promise = new Promise(function(resolve, reject) {
    console.log(3);
    resolve()
}).then(function() {
    console.log(4)
}).then(function() {
    console.log(9)
});

console.log(5)

//主线程任务 1->3->5
//宏任务① setTimeout 2->7->8
//宏任务② setTimeout 10->11->12
//微任务 promise  4->9
//第一轮 1->3->5->4->9
//第二轮 10->11->12
//第三轮 2->7->8
题7
console.log("AAAA"); //①
setTimeout(() => console.log("BBBB"), 1000); //⑥
const start = new Date();
while (new Date() - start < 3000) {}

console.log("CCCC"); //②
setTimeout(() => console.log("DDDD"), 0); //⑦
new Promise((resolve, reject) => {
        console.log("EEEE"); //③
        foo.bar(100);
    })
    .then(() => console.log("FFFF"))
    .then(() => console.log("GGGG"))
    .catch(() => console.log("HHHH")); //⑤
console.log("IIII"); //④

setTimeout(function() {
    console.log('setTimeout'); //⑧
})
//AAAA  CCCC  EEEE  IIII  HHHH BBBB DDDD  setTimeout
题8
async function async1() {
    console.log("AAAA"); //②
    async2();
    console.log("BBBB"); //④
}
async function async2() {
    console.log("CCCC"); //③
}
console.log("DDDD"); //①
setTimeout(function() {
    console.log("FFFF"); //⑧
}, 0);
async1();
new Promise(function(resolve) {
    console.log("GGGG"); //⑤
    resolve();

}).then(function() {
    console.log("HHHH"); //⑦

});
console.log("IIII"); //⑥

//这道题的坑就在于 async中如果没有await,那么它就是一个纯同步函数
//DDDD AAAA CCCC BBBB  GGGG IIII HHHH FFFF
题9
console.log('start'); //①第一轮整体代码
setTimeout(() => {
    console.log('children2'); //③第二轮宏任务
    Promise.resolve().then(() => {
        console.log('children3'); //④微任务
    })
}, 0); //宏任务
new Promise((resolve, reject) => {
    console.log('children4'); //②第一轮整体代码
    setTimeout(() => {
        console.log('children5'); //⑤第三轮宏任务
        resolve('children6') //执行微任务
    }, 0); //宏任务
}).then((res) => { //.then要有resolve才会执行,resolve在setTimeout里暂不执行
    console.log('children7');
    setTimeout(() => {
        console.log('res');
    }, 0)

});
//start children4 children2 children3 children5 children7 children6
题10
  • promise的.then()要有resolve()才会执行
const p = function() {
    return new Promise((resolve, reject) => {
        const p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(1)
            }, 0);
            resolve(2) //resolve2会比resolve1先执行resolve1延迟执行,2执行完1就没了因为promise状态已改变
        })
        p1.then((res) => {
            console.log(res) //③微任务
        })
        console.log(3); //①第一轮整体代码
        resolve(4) //④微任务
    })
}
p().then((res) => {
    console.log(res);
})
console.log('end'); //②第一轮整体代码
//3 end 2 4

博文参考1
博文参考2
JavaScript 运行机制详解:再谈Event Loop
异步讲解

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值