1.同步任务与异步任务
1.1 同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
1.2 异步任务:不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行
任务的优先级:process.nextTick > promise.then > setTimeout > setImmediate
具体来说,异步运行机制如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
2.宏任务与微任务 都是异步任务
async 和 await 在干什么 (https://segmentfault.com/a/1190000007535316) 参考边城大大在学习
async 和 await 执行顺序 https://segmentfault.com/a/1190000011296839 参考边城大大在学习
实际上await是一个让出线程的标志。await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await
后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)
后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入promise队列(Promise的Job Queue)
function testAsync() { console.log("执行testAsync"); return '执行testAsync' } async function test() { console.log("test start"); const v1 = await testSometing(); console.log(v1); const v2 = await testAsync(); console.log(v2); console.log(v1, v2); } test(); var promise = new Promise((resolve)=> { console.log('1'); resolve("promise"); }); promise.then((val)=> console.log(val)); console.log("test end")test start... 执行testSometing promise start.. test end... testSometing 执行testAsync promise hello async testSometing hello async
setTimeout(()=>{ console.log('set1') new Promise(res =>{ res() }).then(()=>{ new Promise( res =>{ res() }).then(()=>{ console.log('then4') }); console.log('then2') }) }) new Promise(res =>{ console.log('pro1') res() }).then(()=>{ console.log('then1') }) setTimeout(()=>{ console.log('set2') }) console.log(2) new Promise(res =>{ res() }).then(()=>{ console.log('then3') }) // 执行结果// pro1,2 , then1, then3, set1, then2, then4, set2
setTimeout(function(){ console.log('定时器开始啦') }); new Promise(function(resolve){ console.log('pro'); setTimeout(function(){ console.log('走定时器') resolve() },0) }).then(function(){ console.log('执行then函数啦') }); //执行结果pro ,定时器开始啦, 走定时器,执行then
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,6,8,2,4,3,5,9,11,10,12 process.nextTick > promise.then > setTimeout > setImmediate