Tus sau tsab xov xwm tshuaj xyuas cov piv txwv ntawm Async/Await hauv JavaScript. Zuag qhia tag nrho, Async / Await yog txoj hauv kev yooj yim los sau cov lej asynchronous. Ua ntej qhov tshwj xeeb no tshwm sim, cov cai no tau sau nrog kev hu rov qab thiab cov lus cog tseg. Tus sau ntawm thawj tsab xov xwm qhia txog qhov zoo ntawm Async/Await los ntawm kev tshuaj xyuas ntau yam piv txwv.
Teeb meem tshwm sim thaum koj xav tau ua ntau yam haujlwm asynchronous ib zaug. Cia peb xav txog qhov xwm txheej no: qhov kev thov yog ua rau Arfat tus neeg siv cov ntaub ntawv, koj yuav tsum nyeem nws qhov profile_img_url thiab rub tawm cov duab los ntawm someserver.com server.
Tom qab rub tawm, peb hloov cov duab mus rau lwm hom, piv txwv li los ntawm PNG rau JPEG. Yog tias qhov kev hloov pauv tau ua tiav, tsab ntawv raug xa mus rau tus neeg siv email. Tom ntej no, cov ntaub ntawv hais txog qhov xwm txheej yog nkag mus rau hauv cov ntaub ntawv transformations.log, qhia hnub tim.
Nws yog ib qho tsim nyog yuav tsum tau them sai sai rau qhov sib tshooj ntawm callbacks thiab ntau tus lej }) nyob rau hauv qhov kawg ntawm cov cai. Nws hu ua Callback Hell lossis Pyramid of Doom.
Qhov tsis zoo ntawm txoj kev no yog pom tseeb:
Txoj cai no nyuaj nyeem.
Nws kuj yog ib qho nyuaj rau kev ua yuam kev, uas feem ntau ua rau cov lej tsis zoo.
Txhawm rau daws qhov teeb meem no, cov lus cog tseg tau ntxiv rau JavaScript. Lawv tso cai rau koj los hloov qhov sib sib zog nqus nesting ntawm callbacks nrog lo lus .ces.
Qhov zoo ntawm cov lus cog tseg yog tias lawv ua kom cov cai nyeem tau zoo dua, los ntawm sab saum toj mus rau hauv qab es tsis yog los ntawm sab laug mus rau sab xis. Txawm li cas los xij, cov lus cog tseg kuj muaj lawv cov teeb meem:
Ntawm no yog ib qho teeb meem uas yuav qhia lub ntsiab lus ntawm lub ntsiab lus kawg.
Piv txwv tias peb muaj lub voj voog uas luam tawm ib ntu ntawm cov lej ntawm 0 txog 10 ntawm qhov sib txawv (0βn vib nas this). Siv cov lus cog tseg, koj yuav tsum tau hloov lub voj no kom cov lej luam tawm hauv ntu ntawm 0 mus rau 10. Yog li, yog tias nws siv sijhawm 6 vib nas this los luam tus xoom thiab 2 vib nas this los luam ib qho, tus lej yuav tsum tau luam tawm ua ntej, thiab tom qab ntawd. lub countdown rau luam ntawv yuav pib.
Thiab tau kawg, peb tsis siv Async/Await lossis .sort los daws qhov teeb meem no. Ib qho piv txwv daws yog thaum kawg.
Async muaj nuj nqi
Qhov sib ntxiv ntawm async functions hauv ES2017 (ES8) ua kom yooj yim txoj haujlwm ntawm kev ua haujlwm nrog cov lus cog tseg. Kuv nco ntsoov tias cov haujlwm async ua haujlwm "sab saum toj" ntawm cov lus cog tseg. Cov haujlwm no tsis sawv cev rau cov ntsiab lus sib txawv zoo. Async functions yog npaj los ua lwm txoj hauv kev uas siv cov lus cog tseg.
Async/Await ua rau nws muaj peev xwm los npaj ua haujlwm nrog asynchronous code nyob rau hauv ib tug synchronous style.
Yog li, paub cov lus cog tseg ua rau nws yooj yim dua kom nkag siab cov ntsiab lus ntawm Async/Await.
syntax
Feem ntau nws muaj ob lo lus tseem ceeb: async thiab tos. Thawj lo lus hloov txoj haujlwm ua asynchronous. Cov haujlwm zoo li no tso cai rau kev siv tos. Hauv lwm qhov xwm txheej, siv qhov haujlwm no yuav ua rau muaj qhov yuam kev.
// With function declaration
async function myFn() {
// await ...
}
// With arrow function
const myFn = async () => {
// await ...
}
function myFn() {
// await fn(); (Syntax Error since no async)
}
Cov haujlwm no tuaj yeem muab tso rau hauv ib qho khoom raws li txoj hauv kev lossis siv hauv kev tshaj tawm hauv chav kawm.
// As an object's method
const obj = {
async getName() {
return fetch('https://www.example.com');
}
}
// In a class
class Obj {
async getResource() {
return fetch('https://www.example.com');
}
}
Async functions yeej zoo ib yam li cov qauv JS ua haujlwm, tab sis muaj kev zam.
Yog li, async functions ib txwm rov qab cog lus:
async function fn() {
return 'hello';
}
fn().then(console.log)
// hello
Tshwj xeeb, fn rov qab txoj hlua nyob zoo. Zoo, txij li qhov no yog ib qho asynchronous muaj nuj nqi, txoj hlua tus nqi yog qhwv hauv cov lus cog tseg uas siv tus tsim.
Nov yog lwm txoj kev tsim yam tsis muaj Async:
function fn() {
return Promise.resolve('hello');
}
fn().then(console.log);
// hello
Hauv qhov no, cov lus cog tseg raug xa rov qab "manually". Ib qho asynchronous muaj nuj nqi yog ib txwm qhwv hauv cov lus cog tseg tshiab.
Yog tias tus nqi xa rov qab yog qhov qub, qhov ua haujlwm async xa rov qab tus nqi los ntawm kev qhwv nws hauv kev cog lus. Yog tias tus nqi xa rov qab yog qhov khoom cog lus, nws qhov kev daws teeb meem raug xa rov qab rau hauv kev cog lus tshiab.
const p = Promise.resolve('hello')
p instanceof Promise;
// true
Promise.resolve(p) === p;
// true
Tab sis yuav ua li cas yog tias muaj qhov yuam kev hauv asynchronous muaj nuj nqi?
async function foo() {
throw Error('bar');
}
foo().catch(console.log);
Yog tias nws tsis ua tiav, foo() yuav rov qab cog lus nrog kev tsis lees paub. Hauv qhov xwm txheej no, Promise.reject uas muaj qhov yuam kev yuav raug xa rov qab los ntawm Promise.resolve.
Async ua haujlwm ib txwm tso tawm cov lus cog tseg, tsis hais dab tsi rov qab los.
// utility function to cause delay
// and get random value
const delayAndGetRandom = (ms) => {
return new Promise(resolve => setTimeout(
() => {
const val = Math.trunc(Math.random() * 100);
resolve(val);
}, ms
));
};
async function fn() {
const a = await 9;
const b = await delayAndGetRandom(1000);
const c = await 5;
await delayAndGetRandom(1000);
return a + b * c;
}
// Execute fn
fn().then(console.log);
Thiab ntawm no yog cov lus piav qhia txog yuav ua li cas fn muaj nuj nqi ua haujlwm.
Tom qab hu nws, thawj kab yog hloov los ntawm const a = tos 9; hauv const a = await Promise.resolve(9);.
Tom qab siv Await, qhov kev ua haujlwm raug tshem tawm kom txog thaum tau txais nws tus nqi (hauv qhov xwm txheej tam sim no nws yog 9).
ncuaAndGetRandom(1000) ncua qhov kev ua tiav ntawm fn muaj nuj nqi kom txog thaum nws ua tiav nws tus kheej (tom qab 1 thib ob). Qhov no zoo nres fn muaj nuj nqi rau 1 thib ob.
ncuaAndGetRandom(1000) ntawm kev daws rov qab tus nqi random, uas yog muab rau qhov sib txawv b.
Zoo, rooj plaub uas muaj qhov sib txawv c zoo ib yam li rooj plaub uas muaj qhov sib txawv a. Tom qab ntawd, txhua yam nres rau ib pliag, tab sis tam sim no ncuaAndGetRandom(1000) rov qab tsis muaj dab tsi vim nws tsis tas yuav tsum tau ua.
Yog li ntawd, cov txiaj ntsig tau suav nrog cov qauv a + b * c. Cov txiaj ntsig tau muab qhwv rau hauv kev cog lus siv Promise.resolve thiab xa rov qab los ntawm kev ua haujlwm.
Cov kev ncua no tuaj yeem nco txog cov tshuab hluav taws xob hauv ES6, tab sis muaj qee yam rau nws koj vim li cas.
daws qhov teeb meem
Zoo, tam sim no cia saib cov kev daws teeb meem uas tau hais los saum toj no.
Lub finishMyTask muaj nuj nqi siv Await tos rau cov txiaj ntsig ntawm kev ua haujlwm xws li queryDatabase, sendEmail, logTaskInFile, thiab lwm yam. Yog tias koj piv cov tshuaj no nrog rau qhov uas tau cog lus tseg, qhov zoo sib xws yuav pom tseeb. Txawm li cas los xij, Async/Await version ua kom yooj yim rau tag nrho cov syntactic complexities. Nyob rau hauv rooj plaub no, tsis muaj coob tus callbacks thiab chains zoo li .then/.catch.
Ntawm no yog ib qho kev daws teeb meem nrog cov zis ntawm cov lej, muaj ob txoj kev xaiv.
const wait = (i, ms) => new Promise(resolve => setTimeout(() => resolve(i), ms));
// Implementation One (Using for-loop)
const printNumbers = () => new Promise((resolve) => {
let pr = Promise.resolve(0);
for (let i = 1; i <= 10; i += 1) {
pr = pr.then((val) => {
console.log(val);
return wait(i, Math.random() * 1000);
});
}
resolve(pr);
});
// Implementation Two (Using Recursion)
const printNumbersRecursive = () => {
return Promise.resolve(0).then(function processNextPromise(i) {
if (i === 10) {
return undefined;
}
return wait(i, Math.random() * 1000).then((val) => {
console.log(val);
return processNextPromise(i + 1);
});
});
};
Thiab ntawm no yog kev daws teeb meem siv async functions.
async function printNumbersUsingAsync() {
for (let i = 0; i < 10; i++) {
await wait(i, Math.random() * 1000);
console.log(i);
}
}
Tuav yuam kev
Unhandled yuam kev yog qhwv hauv cov lus cog tseg tsis lees paub. Txawm li cas los xij, async functions tuaj yeem siv sim / ntes los daws cov teeb meem synchronously.
async function canRejectOrReturn() {
// wait one second
await new Promise(res => setTimeout(res, 1000));
// Reject with ~50% probability
if (Math.random() > 0.5) {
throw new Error('Sorry, number too big.')
}
return 'perfect number';
}
canRejectOrReturn() yog ib qho kev ua haujlwm asynchronous uas ua tiav ("tus lej zoo meej") lossis ua tsis tiav nrog qhov yuam kev ("Thov txim, tus lej loj dhau").
Txij li cov piv txwv saum toj no cia siab tias canRejectOrReturn ua kom tiav, nws tus kheej tsis ua haujlwm yuav ua rau kev ua tiav ntawm kev ntes thaiv. Raws li qhov tshwm sim, qhov ua haujlwm foo yuav xaus nrog qhov tsis tau hais tseg (thaum tsis muaj dab tsi rov qab los hauv kev sim thaiv) lossis nrog qhov yuam kev ntes. Raws li qhov tshwm sim, qhov haujlwm no yuav tsis poob vim qhov sim / ntes yuav ua haujlwm foo nws tus kheej.
Nws yog ib qho tsim nyog them sai sai rau qhov tseeb tias hauv qhov piv txwv, canRejectOrReturn rov qab los ntawm foo. Foo nyob rau hauv cov ntaub ntawv no yog txiav nrog ib tug zoo meej tooj los yog xa rov qab qhov yuam kev ("Thov txim, tus lej loj dhau"). Lub catch block yuav tsis raug tua.
Qhov teeb meem yog tias foo rov qab cov lus cog tseg dhau los ntawm canRejectOrReturn. Yog li kev daws rau foo dhau los ua kev daws teeb meem rau canRejectOrReturn. Hauv qhov no, cov cai yuav muaj tsuas yog ob kab:
Hauv cov cai saum toj no, foo yuav tawm mus ua tiav nrog ob tus lej zoo meej thiab qhov yuam kev raug ntes. Yuav tsis muaj qhov tsis lees paub ntawm no. Tab sis foo yuav rov qab nrog canRejectOrReturn, tsis yog nrog undefined. Cia peb ua kom paub tseeb qhov no los ntawm kev tshem tawm qhov rov qab tuaj tos canRejectOrReturn() kab:
Nws tsim nyog them nyiaj rau Await hauv .map callback. Cov suav ntawm no yog cov lus cog tseg, thiab .map yog qhov tsis qhia npe hu rov qab rau txhua tus neeg siv.
Kev siv ntau dhau ntawm tos
Cia peb coj tus lej no ua piv txwv:
async function fetchAllCounts(users) {
const counts = [];
for (let i = 0; i < users.length; i++) {
const username = users[i];
const count = await fetchPublicReposCount(username);
counts.push(count);
}
return counts;
}
Ntawm no tus naj npawb repo tau muab tso rau hauv suav qhov sib txawv, ces tus lej no tau ntxiv rau cov suav array. Qhov teeb meem nrog cov cai yog kom txog thaum thawj tus neeg siv cov ntaub ntawv tuaj txog ntawm lub server, tag nrho cov neeg siv tom ntej yuav nyob hauv hom standby. Yog li, tsuas yog ib tus neeg siv tau ua tiav ntawm ib lub sijhawm.
Yog tias, piv txwv li, nws yuav siv li 300 ms los ua ib tus neeg siv, tom qab ntawd rau txhua tus neeg siv nws twb yog thib ob; lub sijhawm siv linearly nyob ntawm tus naj npawb ntawm cov neeg siv. Tab sis txij li thaum tau txais tus naj npawb ntawm repo tsis nyob ntawm ib leeg, cov txheej txheem tuaj yeem sib npaug. Qhov no yuav tsum tau ua haujlwm nrog .map thiab Promise.all:
Promise.all tau txais ib qho array ntawm cov lus cog tseg raws li cov tswv yim thiab xa rov qab cov lus cog tseg. Tom qab tag nrho, tom qab tag nrho cov lus cog tseg nyob rau hauv lub array tau ua tiav los yog nyob rau hauv thawj qhov kev tsis lees paub, ua tiav. Tej zaum nws yuav tshwm sim tias lawv txhua tus tsis pib tib lub sijhawm - txhawm rau kom ntseeg tau tias pib ib txhij, koj tuaj yeem siv p-map.
xaus
Async functions tau dhau los ua qhov tseem ceeb rau kev txhim kho. Zoo, rau kev hloov pauv ntawm async zog, koj yuav tsum siv Async Iterators. Tus tsim tawm JavaScript yuav tsum tau paub zoo hauv qhov no.