มีคำถามเกี่ยวกับ JavaScript ครับ

Code 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
ครับ
คำตอบที่ได้รับเลือกจากเจ้าของกระทู้
ความคิดเห็นที่ 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
แสดงความคิดเห็น
โปรดศึกษาและยอมรับนโยบายข้อมูลส่วนบุคคลก่อนเริ่มใช้งาน อ่านเพิ่มเติมได้ที่นี่