JS Async / Await vs Promise vs Callbacks

Sep 14 2020

ฉันพยายามเข้าใจความแตกต่างระหว่างการโทรกลับและสัญญา 3 ข้อนี้ชัดเจน แต่ฉันไม่ได้รับการใช้ async / await ฉันรู้ว่ามันเป็นน้ำตาลแห่งคำสัญญา แต่สิ่งที่ฉันพยายามแล้วไม่ได้ผล ฉันกำลังแบ่งปันรหัสที่ฉันพยายามทำความเข้าใจทั้งหมดนี้ ...

ฉันได้ลองใช้อาร์เรย์แล้ว

var array = [1,2,3];

และ 2 ฟังก์ชั่น

  • get() ดำเนินการใน 1 วินาทีและคอนโซลไฟล์ array
  • post(item) ดำเนินการใน 2 วินาทีและผลักดันรายการใหม่ในไฟล์ array

ตอนนี้สิ่งที่ฉันต้องการที่จะได้รับก็คือpostวิธีการที่ควรจะดำเนินการเป็นครั้งแรกและgetหลังจากที่มันเพื่อให้ผลบนคอนโซลที่ควรจะเป็น[1,2,3,4]ไม่ได้[1,2,3]

โทรกลับ

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

ใช้งานได้ดี แต่ในกรณีที่มีการโทรกลับมากเกินไปรหัสจะยุ่งกว่า ...

สัญญา

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

ตกลงด้วยรหัสที่สะอาดกว่ามาก แต่ยังthenโทรหลายครั้ง... ตอนนี้

Async / รอ

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

เวอร์ชันที่สะอาดกว่ามาก แต่ก็ไม่ได้ผล ... ฉันได้ลองแล้วด้วย (แปลงทั้งสองฟังก์ชัน ( post& get) เป็น async และโทรด้วยthen)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

แต่ยังไม่มีประโยชน์ ดังนั้นฉันจึงสับสนโดยสิ้นเชิงเกี่ยวกับคุณสมบัตินี้ (เช่น async / await) โปรดอธิบายอย่างละเอียดเกี่ยวกับตัวอย่างนี้ และโปรดบอกฉันเกี่ยวกับPromise.resolve& Promise.allในบริบทเดียวกันนี้ด้วย! ขอบคุณ

คำตอบ

3 Quentin Sep 13 2020 at 22:35

asyncและawaitเป็นเครื่องมือในการจัดการคำสัญญา

await post(4);

ที่นี่คุณกำลังรอคำสัญญาที่จะกลับมาpostเพื่อแก้ไข

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

อย่างไรก็ตามpost ไม่คืนคำสัญญาดังนั้นจึงไม่มีประโยชน์อะไร

คุณเคยดำเนินการตามpostสัญญามาก่อน ดังนั้นใช้สิ่งนั้น:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}
2 trincot Sep 13 2020 at 22:38

ความพยายามของคุณด้วยasyncและawaitไม่ได้ใช้อะไรที่แก้ไขสัญญาหลังจากที่ล่าช้า ตามที่กล่าวมาasyncฟังก์ชันทั้งหมดที่คุณกำหนดไว้จะส่งคืนคำสัญญาที่แก้ไขได้ทันที

คุณจะต้องใช้ฟังก์ชันยูทิลิตี้ที่คุณสามารถใช้ได้บ่อยๆ จะส่งคืนคำสัญญาที่แก้ไขหลังจากจำนวนมิลลิวินาทีที่กำหนดโดยใช้setTimeout:

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

1 tawfiknasser Sep 13 2020 at 22:31

คล้ายกับสิ่งที่คุณทำในPROMISE

ตัดโพสต์ setTimeout ในสัญญาและส่งคืน
โทรแก้ไขภายในเนื้อหาของ settimeout

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

จากนั้นคุณสามารถใช้งานได้ดังนี้:

async function init() {
    await post(4);
    get();
    }