คำตอบที่ได้รับเลือกจากเจ้าของกระทู้
ความคิดเห็นที่ 3
js runtime เหมือนกับ python กล่าวคือเป็น single thread
ยกเว้นเรียก new worker(fileurl.js) ถึงจะ spawn thread
แล้วสื่อสารกันผ่าน postmessage, onmessage event
ส่วน await จะแขวน suspension point ใน runtime แล้วไปหา resume point ที่มีใน suspension queque
ซึ่งทั้งหมดทั้งมวล จะเป็นเพียงแค่ message loop ใน UI thread ที่เป็น single thread เท่านั้น
ปัญหาคือ เจ้า setTimeout มันไม่ใช่ awaitable ไม่ใช่ promise
ดังนั้น await ไปก็ไม่เกิดอะไร
มันก็จะเหมือนกับ setTimeout มาต่อ ๆ กันเฉย ๆ
setTimeout(()=>{console.log("Do1")
return ("Do1")},3000);
setTimeout(()=>{console.log("Do2")
return ("Do2")},2000);
setTimeout(()=>{console.log("Do3")
return ("Do3")},1000);
นั่นคือ แขวน lambda ใน queue โดยมี timeout ตามที่กำหนด
ผลคือรัน lambda เรียงตามน้อยไปหามาก นั่นเอง
ถ้า ต้องการรันเรียง
await a()
await b()
await c()
แล้ว ก็ต้องเปลี่ยน setTimeout ให้เป็น awaitable ให้เป็น Promise
จะได้ await ได้จริง
วิธี คือ ต้องยัด setTimeout ลงใน ctor ของ Promise
โดยที่ยัด resolve ที่เป็นหนึ่งใน lambda parameter ใน lambda ของ ctor ของ Promise
ลงไปใน setTimeout อีกที
เพื่อแขวน resolve ให้เป็น suspension point เวลาถูก await
ซึ่ง resolve จะถูก resumed เมื่อพ้นเวลา timeout นั่นเอง
const sleep = waitms => new Promise(resolve => setTimeout(resolve, waitms))
[LIVE]
หรืออีกที เปลี่ยน a(),b(),c() ให้คืนเป็น Promise object ตั้งแต่แรกเลยก็ได้
[LIVE]
Promise ctor
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
ยกเว้นเรียก new worker(fileurl.js) ถึงจะ spawn thread
แล้วสื่อสารกันผ่าน postmessage, onmessage event
ส่วน await จะแขวน suspension point ใน runtime แล้วไปหา resume point ที่มีใน suspension queque
ซึ่งทั้งหมดทั้งมวล จะเป็นเพียงแค่ message loop ใน UI thread ที่เป็น single thread เท่านั้น
ปัญหาคือ เจ้า setTimeout มันไม่ใช่ awaitable ไม่ใช่ promise
ดังนั้น await ไปก็ไม่เกิดอะไร
มันก็จะเหมือนกับ setTimeout มาต่อ ๆ กันเฉย ๆ
setTimeout(()=>{console.log("Do1")
return ("Do1")},3000);
setTimeout(()=>{console.log("Do2")
return ("Do2")},2000);
setTimeout(()=>{console.log("Do3")
return ("Do3")},1000);
นั่นคือ แขวน lambda ใน queue โดยมี timeout ตามที่กำหนด
ผลคือรัน lambda เรียงตามน้อยไปหามาก นั่นเอง
ถ้า ต้องการรันเรียง
await a()
await b()
await c()
แล้ว ก็ต้องเปลี่ยน setTimeout ให้เป็น awaitable ให้เป็น Promise
จะได้ await ได้จริง
วิธี คือ ต้องยัด setTimeout ลงใน ctor ของ Promise
โดยที่ยัด resolve ที่เป็นหนึ่งใน lambda parameter ใน lambda ของ ctor ของ Promise
ลงไปใน setTimeout อีกที
เพื่อแขวน resolve ให้เป็น suspension point เวลาถูก await
ซึ่ง resolve จะถูก resumed เมื่อพ้นเวลา timeout นั่นเอง
const sleep = waitms => new Promise(resolve => setTimeout(resolve, waitms))
[LIVE]
หรืออีกที เปลี่ยน a(),b(),c() ให้คืนเป็น Promise object ตั้งแต่แรกเลยก็ได้
[LIVE]
Promise ctor
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
แสดงความคิดเห็น
อ่านกระทู้อื่นที่พูดคุยเกี่ยวกับ
JavaScript
การพัฒนา Desktop Application
การพัฒนา Web Application
การพัฒนา Mobile Application
การพัฒนาซอฟต์แวร์
มีคำถามเกี่ยวกับ JavaScript ครับ
async function AWWW() {
await a()
await b()
await c()
}
async function a(){
setTimeout(()=>{console.log("Do1")
return ("Do1")},3000)
}
async function b(){
setTimeout(()=>{console.log("Do2")
return ("Do2")},2000)
}
async function c(){
setTimeout(()=>{console.log("Do3")
return ("Do3")},1000)
}
AWWW()
-----------------------------------------------------------------------------------------
ตอนนี้เมื่อรันสคริปแล้ว ผลออกมาเป็น
Do3
Do2
Do1
จะเขียนใหม่ยังไงให้ ผลออกมาเป็น
Do1
Do2
Do3
ครับ