javascript巨集任務和微任務
阿新 • • 發佈:2019-01-13
函式
// 你不能改變一個函式的 name 屬性的值, 因為該屬性是隻讀的
var object = {
// someMethod 屬性指向一個匿名函式
someMethod: function() { }
};
object.someMethod.name = "otherMethod";
console.log(object.someMethod.name); // someMethod
函式的length屬性等於該函式宣告時所要傳入的新引數量
通過arguments.length,可以知道在呼叫時傳入了多個引數
setTimeout()和setInterval()的區別
setTimeout(()=>{ console.log('執行setTimeout') },1000) setInterval(()=>{ console.log('執行setInterval') },1000) setTimeout是執行並延遲1s執行 只有滿足 (1)3秒後 (2)主執行緒空閒,同時滿足時,才會3秒後執行該函式 setInterval是每隔1s就嘗試執行
event loop的概念
微任務 promise process.nextTick
巨集任務 setTimeout setInterval I/O script
同一次事件迴圈中 微任務永遠在巨集任務之前執行
setTimeout(function(){ console.log('定時器開始啦') }); new Promise(function(resolve){ console.log('馬上執行for迴圈啦'); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log('執行then函式啦') }); console.log('程式碼執行結束');
首先執行script下的巨集任務,遇到setTimeout,將其放到巨集任務的【佇列】裡 遇到 new Promise直接執行,列印"馬上執行for迴圈啦" 遇到then方法,是微任務,將其放到微任務的【佇列裡】 列印 "程式碼執行結束" 本輪巨集任務執行完畢,檢視本輪的微任務,發現有一個then方法裡的函式, 列印"執行then函式啦" 到此,本輪的event loop 全部完成。 下一輪的迴圈裡,先執行一個巨集任務,發現巨集任務的【佇列】裡有一個 setTimeout裡的函式,執行列印"定時器開始啦"
【馬上執行for迴圈啦 --- 程式碼執行結束 --- 執行then函式啦 --- 定時器開始啦】
async function fn1(){
return 123
}
function fn2(){
return 123
}
console.log(fn1())
console.log(fn2())
//返回
Promise {<resolved>: 123}
123
-----
new promise(()=>{
同步的
}).then(
非同步的微任務
)
第二題
setTimeout(() => console.log('setTimeout1'), 0); //1巨集任務
setTimeout(() => { //2巨集任務
console.log('setTimeout2');
Promise.resolve().then(() => {
console.log('promise3');
Promise.resolve().then(() => {
console.log('promise4');
})
console.log(5)
})
setTimeout(() => console.log('setTimeout4'), 0); //4巨集任務
}, 0);
setTimeout(() => console.log('setTimeout3'), 0); //3巨集任務
Promise.resolve().then(() => {//1微任務
console.log('promise1');
})
第三題
async function async1() {
console.log( 'async1 start' )
await async2()
console.log( 'async1 end' )
}
async function async2() {
console.log( 'async2' )
}
async1()
console.log( 'script start' )
執行結果
async1 start
async2
script start
async1 end
一旦遇到await 就立刻讓出執行緒,阻塞後面的程式碼
等候之後,對於await來說分兩種情況
- 不是promise 物件
- 是promise物件
如果不是promise,await會阻塞後面的程式碼,先執行async外面的同步程式碼,同步程式碼執行完畢後,在回到async內部,把promise的東西,作為await表示式的結果
如果它等到的是一個 promise 物件,await 也會暫停async後面的程式碼,先執行async外面的同步程式碼,等著 Promise 物件 fulfilled,然後把 resolve 的引數作為 await 表示式的運算結果。
如果一個 Promise 被傳遞給一個 await 操作符,await 將等待 Promise 正常處理完成並返回其處理結果。
第四題
async function async1() {
console.log( 'async1 start' ) //2
await async2()
console.log( 'async1 end' )//7
}
async function async2() {
console.log( 'async2' )//3
}
console.log( 'script start' ) //1
setTimeout( function () {
console.log( 'setTimeout' )//8
}, 0 )
async1();
new Promise( function ( resolve ) {
console.log( 'promise1' )//4
resolve();
} ).then( function () {
console.log( 'promise2' ) //6
} )
console.log( 'script end' )//5
控制檯執行任何語句都認為是在一個匿名函式空間包裹下的,JS函式return; 和不寫return都是預設返回undefined,所以會在控制檯下輸出undefined
第五題
new Promise( ( resolve, reject ) => {
console.log( "promise1" )
resolve()
} )
.then( () => {
console.log( 1 )
} )
.then( () => {
console.log( 2 )
} )
.then( () => {
console.log( 3 )
} )
new Promise( ( resolve, reject ) => {
console.log( "promise2" )
resolve()
} )
.then( () => {
console.log( 4 )
} )
.then( () => {
console.log( 5 )
} )
.then( () => {
console.log( 6 )
} )
// 1 4 2 5 3 6
先執行同步程式碼 promise1, promise2,此時微任務有兩個任務 log(1)和log(4)
執行完log(1)和log(4)此時任務中有log(2)和log(5)兩個微任務
執行log(2)和log(5)此時任務中有log(3)和log(6)兩個微任務
連續的幾個
then()
回撥,並不是連續的建立了一系列的微任務並推入微任務佇列,因為then()
的返回值必然是一個Promise
,而後續的then()
是上一步then()
返回的Promise
的回撥
ECS(執行環境棧)
function foo(i) {
if (i < 0) return;
console.log('begin:' + i);
foo(i - 1);
console.log('end:' + i);
}
foo(2);
// 輸出:
// begin:2
// begin:1
// begin:0
// end:0
// end:1
// end:2
執行棧既是函式在執行時儲存呼叫過程的棧,同樣的,採取呼叫形式進行佇列,先進後出的方式
第六題
async function t1 () {
console.log(1)
console.log(2)
await Promise.resolve().then(() => console.log('t1p'))
console.log(3)
console.log(4)
}
async function t2() {
console.log(5)
console.log(6)
await Promise.resolve().then(() => console.log('t2p'))
console.log(7)
console.log(8)
}
t1()
t2()
console.log('end')
// 輸出:
// 1
// 2
// 5
// 6
// end
// t1p
// t2p
// 3
// 4
// 7
// 8
// undefined
第七題
async function t1 () {
console.log(1)
console.log(2)
await new Promise(resolve => {
setTimeout(() => {
console.log('t1p')
resolve()
}, 1000)
})
await console.log(3)
console.log(4)
}
async function t2() {
console.log(5)
console.log(6)
await Promise.resolve().then(() => console.log('t2p'))
console.log(7)
console.log(8)
}
t1()
t2()
console.log('end')
// 輸出:
// 1
// 2
// 5
// 6
// end
// t2p
// 7
// 8
// undefined
// t1p
// 3
// 4