Open suochantsao opened 5 months ago
Event loop 動畫示意: http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D 有示意圖片文章: https://www.javascripttutorial.net/javascript-event-loop/
是為了解決 JavaScript 單執行緒的設計而在特定執行環境中所提供的一個實現異步的解決機制。
JavaScript 這個語言在當初設計的時候就設定為單執行緒,而單執行序的意思即為每一行程式碼執行完畢後,才會往下一行的程式碼去執行。 一次只能做一件事情的特性就屬於單執行序,生活化的例子: 一間咖啡廳只有老闆一個人,所以他要包辦接待客人、點餐、製作咖啡或餐點、送餐、結帳和清潔等工作,而且當他在接待客人入座時,他沒有辦法去幫其他客人點餐或是送餐等服務,只能等他接待完客人後再繼續進行其他服務。
JavaScript 是一個語言,它需要有執行環境才能夠使用。(像是世界上有很多語言,但需要透過人來說和寫才能應用該語言一樣) 除了我們常見的瀏覽器 Browser 以外,還有 Node.js 的環境也可以運行 JavaScript 程式碼。 所以換句話說, Event loop 這個機制是執行環境(也就是瀏覽器或是 Node.js )所提供的,JavaScript 本身並沒有 Event loop 這個功能。
異步是指當主要的線程在執行程式碼時,可以同時進行其他的程式碼的特性。
如剛才提到的,事件循環 Event loop 的出現是為了要解決單執行緒的問題,因為如果每次執行一行程式碼的時候都要等前面的執行完才能再觸發下一行的話,這樣使用者體驗會很大程度的被影響。 舉例:延伸我們剛才提到的咖啡廳例子,如果老闆在甜點製作或是手沖咖啡的過程中都等到餐點做完才去進行下一個服務,可想而知門口在等的客人一定會客訴。 那 Event loop 要做的事情是什麼?就是在老闆等待蛋糕烘焙的過程中去做接待客人或是清潔桌面甚至是點餐的服務,直到蛋糕烘焙結束後,老闆再去做對應的後續動作(可能是切蛋糕然後放進冰箱或是送餐到客人桌上)
要介紹 Event loop 的執行過程,那就免不了介紹這個機制背後的主要概念。 這裡放我自己畫的圖
棧 (Stack):採用後進先出的規則,當函式執行時,會被添加到棧的頂部,當執行完成時,就會從頂部移出,直到棧被清空
console.log
setTimeOut
等都是屬於這個範疇。( console.log
實際上使用的是 window.console.log
,只不過 window
是被允許省略的)隊列 (Queue):也是一種數據結構,特性是先進先出 (FIFO)。
2.
console.log("Start");
function waitFor(duration) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Waited for ${duration} milliseconds.`);
}, duration);
});
}
async function runAsyncTasks() {
const result1 = await waitFor(2000);
console.log(result1);
const result2 = await waitFor(1000);
console.log(result2);
}
runAsyncTasks();
console.log("End");
const orderPizza = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Pizza is here!");
}, 2000);
});
console.log("Placing pizza order...");
orderPizza.then((result) => { console.log(result); });
console.log("Continuing with other tasks...");
const orderPizza = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Pizza is here!");
}, 2000);
});
const orderSoda = new Promise((resolve) => { setTimeout(() => { resolve("Soda is here!"); }, 1000); });
console.log("Placing pizza order...");
orderPizza .then((result) => { console.log(result); return orderSoda; // Chain the soda order }) .then((result) => { console.log(result); });
console.log("Continuing with other tasks...");
5.
async function visitMansion() {
console.log("Entering the library...");
await readBook();
console.log("Leaving the library...");
console.log("Entering the conservatory...");
await enjoyPlants();
console.log("Leaving the conservatory...");
console.log("Entering the ballroom...");
await dance();
console.log("Leaving the ballroom...");
}
async function readBook() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Reading a book...");
resolve();
}, 2000);
});
}
async function enjoyPlants() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Admiring plants...");
resolve();
}, 1500);
});
}
async function dance() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("Dancing...");
resolve();
}, 1000);
});
}
visitMansion();
6.
console.log('start');
new Promise((resolve) => {
console.log('promise exec');
resolve();
console.log('promise after resolve');
}).then(() => {
console.log('promise then');
})
setTimeout(() => {
console.log('setTimeout exec');
})
console.log('end');