JS Async / Await vs Promise vs Callbacks
ฉันพยายามเข้าใจความแตกต่างระหว่างการโทรกลับและสัญญา 3 ข้อนี้ชัดเจน แต่ฉันไม่ได้รับการใช้ async / await ฉันรู้ว่ามันเป็นน้ำตาลแห่งคำสัญญา แต่สิ่งที่ฉันพยายามแล้วไม่ได้ผล ฉันกำลังแบ่งปันรหัสที่ฉันพยายามทำความเข้าใจทั้งหมดนี้ ...
ฉันได้ลองใช้อาร์เรย์แล้ว
var array = [1,2,3];
และ 2 ฟังก์ชั่น
get()ดำเนินการใน 1 วินาทีและคอนโซลไฟล์arraypost(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ในบริบทเดียวกันนี้ด้วย! ขอบคุณ
คำตอบ
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)); }
ความพยายามของคุณด้วย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...");
คล้ายกับสิ่งที่คุณทำในPROMISE
ตัดโพสต์ setTimeout ในสัญญาและส่งคืน
โทรแก้ไขภายในเนื้อหาของ settimeout
function post(item) {
return new Promise((resolve)=>{
setTimeout(() => {
array.push(item)
resolve()
}, 2000);
})
}
จากนั้นคุณสามารถใช้งานได้ดังนี้:
async function init() {
await post(4);
get();
}