Tiyeni tiwone Async/Await mu JavaScript pogwiritsa ntchito zitsanzo
Wolemba nkhaniyi akuwunika zitsanzo za Async/Await mu JavaScript. Ponseponse, Async/Await ndi njira yabwino yolembera ma code asynchronous. Izi zisanachitike, code yotereyi idalembedwa pogwiritsa ntchito ma callbacks ndi malonjezo. Wolemba nkhani yoyambirira amawulula zabwino za Async/Await posanthula zitsanzo zosiyanasiyana.
Tikukukumbutsani:kwa owerenga onse a Habr - kuchotsera ma ruble 10 polembetsa maphunziro aliwonse a Skillbox pogwiritsa ntchito nambala yotsatsira ya Habr.
Skillbox imalimbikitsa: Maphunziro aulere pa intaneti "Wopanga Java".
callback
Callback ndi ntchito yomwe kuyimba kwake kumachedwetsedwa mpaka kalekale. M'mbuyomu, ma callbacks ankagwiritsidwa ntchito m'madera a code komwe zotsatira zake sizinkapezeka nthawi yomweyo.
Nachi chitsanzo cha kuwerenga mosasunthika fayilo mu Node.js:
// With function declaration
async function myFn() {
// await ...
}
// With arrow function
const myFn = async () => {
// await ...
}
function myFn() {
// await fn(); (Syntax Error since no async)
}
Async imayikidwa kumayambiriro kwenikweni kwa chilengezo cha ntchito, ndipo ngati ntchito ya muvi, pakati pa "="" chizindikiro ndi makolo.
// 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');
}
}
NB! Ndikoyenera kukumbukira kuti omanga kalasi ndi ma getters/setter sangakhale asynchronous.
Semantics ndi malamulo akupha
Ntchito za Async ndizofanana ndi ntchito za JS, koma pali zosiyana.
Chifukwa chake, ntchito za async nthawi zonse zimabwezera malonjezo:
async function fn() {
return 'hello';
}
fn().then(console.log)
// hello
Makamaka, fn imabwezera chingwe moni. Chabwino, popeza iyi ndi ntchito yofanana, mtengo wa chingwe umakutidwa ndi lonjezo pogwiritsa ntchito womanga.
Nayi njira ina yopanda Async:
function fn() {
return Promise.resolve('hello');
}
fn().then(console.log);
// hello
Pachifukwa ichi, lonjezolo likubwezeredwa "pamanja". Ntchito ya asynchronous nthawi zonse imakutidwa ndi lonjezo latsopano.
Ngati mtengo wobwezera ndi wachikale, ntchito ya async imabwezeretsa mtengowo poukulunga mu lonjezo. Ngati mtengo wobwezera ndi chinthu cholonjeza, chigamulo chake chimabwezeredwa mu lonjezo latsopano.
const p = Promise.resolve('hello')
p instanceof Promise;
// true
Promise.resolve(p) === p;
// true
Koma chimachitika ndi chiyani ngati pali cholakwika mkati mwa ntchito ya asynchronous?
async function foo() {
throw Error('bar');
}
foo().catch(console.log);
Ngati sichinasinthidwe, foo() ibweza lonjezo ndikukanidwa. Zikatero, Promise.reject yomwe ili ndi cholakwika ibwezedwa m'malo mwa Promise.resolve.
Ntchito za Async nthawi zonse zimatulutsa lonjezo, mosasamala kanthu za zomwe zabwezedwa.
Ntchito za Asynchronous zimayima nthawi zonse.
Kudikira kumakhudza mawu. Chifukwa chake, ngati mawuwo ndi lonjezo, ntchito ya async imayimitsidwa mpaka lonjezolo litakwaniritsidwa. Ngati mawuwa sali lonjezo, amasinthidwa kukhala lonjezo kudzera pa Promise.resolve ndiyeno kumalizidwa.
// 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);
Ndipo apa pali kufotokozera momwe fn ntchito imagwirira ntchito.
Atatha kuyitcha, mzere woyamba umasinthidwa kuchokera ku const a = wait 9; mu const a = ait Promise.resolve(9);.
Mukamagwiritsa ntchito Kudikira, ntchitoyo imayimitsidwa mpaka a itapeza mtengo wake (pakali pano ndi 9).
delayAndGetRandom(1000) imayimitsa kaye ntchito ya fn mpaka itamaliza yokha (pambuyo pa sekondi imodzi). Izi zimayimitsa ntchito ya fn kwa sekondi imodzi.
delayAndGetRandom(1000) kudzera kusolve imabweretsa mtengo wachisawawa, womwe umaperekedwa ku b.
Chabwino, vuto la variable c ndi lofanana ndi la variable a. Pambuyo pake, chilichonse chimayima kamphindi, koma tsopano kuchedwaAndGetRandom(1000) sikubweza chilichonse chifukwa sizofunikira.
Zotsatira zake, zikhalidwe zimawerengedwa pogwiritsa ntchito formula a + b * c. Zotsatira zake zimakutidwa ndi lonjezo pogwiritsa ntchito Promise.resolve ndikubwezeredwa ndi ntchitoyi.
Kuyimitsa uku kungakhale ngati kukumbukira majenereta mu ES6, koma pali china chake zifukwa zanu.
The finishMyTask ntchito imagwiritsa ntchito Await kudikirira zotsatira za ntchito monga queryDatabase, sendEmail, logTaskInFile, ndi ena. Mukayerekezera yankho limeneli ndi limene malonjezo anagwiritsidwa ntchito, kufanana kwake kudzaonekera. Komabe, mtundu wa Async/Await umathandizira kwambiri zovuta zonse. Pamenepa, palibe chiwerengero chachikulu cha ma callbacks ndi maunyolo monga .then/.catch.
Pano pali yankho ndi linanena bungwe manambala, pali njira ziwiri.
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);
});
});
};
Ndipo apa pali yankho ntchito async ntchito.
async function printNumbersUsingAsync() {
for (let i = 0; i < 10; i++) {
await wait(i, Math.random() * 1000);
console.log(i);
}
}
Kukonza zolakwika
Zolakwa zosasamalidwa zimakutidwa ndi lonjezo lokanidwa. Komabe, ntchito za async zitha kugwiritsa ntchito kuyesa / kugwira kuthana ndi zolakwika mogwirizana.
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() ndi ntchito yofananira yomwe imapambana ("nambala yabwino") kapena kulephera ndi cholakwika ("Pepani, nambala yayikulu kwambiri").
Monga mukuonera, palibe kuyembekezera kapena kubwerera mu code. Chifukwa chake foo nthawi zonse amatuluka ndi undefined popanda kuchedwa 1 sekondi. Koma lonjezolo lidzakwaniritsidwa. Ngati iponya cholakwika kapena kukana, ndiye UnhandledPromiseRejectionWarning idzayitanidwa.
Ntchito za Async mu Callbacks
Ntchito za Async zimagwiritsidwa ntchito nthawi zambiri mu .map kapena .sefa ngati ma callbacks. Chitsanzo ndi ntchito ya fetchPublicReposCount(username), yomwe imabweza kuchuluka kwa nkhokwe zotseguka pa GitHub. Tiyerekeze kuti pali ogwiritsa ntchito atatu omwe timafunikira ma metric. Nayi code ya ntchitoyi:
Ndikoyenera kutchera khutu ku Await mu .map callback. Pano kuwerengera ndi malonjezo angapo, ndipo .map ndi kuyitananso mosadziwika kwa wogwiritsa ntchito aliyense.
Kugwiritsa ntchito mopitilira muyeso kudikirira
Tiyeni titenge code iyi mwachitsanzo:
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;
}
Pano nambala ya repo imayikidwa mu chiwerengero chowerengera, ndiye nambala iyi imawonjezedwa kumagulu owerengera. Vuto la code ndiloti mpaka deta ya wogwiritsa ntchito yoyamba ifike kuchokera ku seva, ogwiritsa ntchito onse omwe akutsatira adzakhala mu mode standby. Chifukwa chake, wogwiritsa ntchito m'modzi yekha amakonzedwa panthawi imodzi.
Ngati, mwachitsanzo, zimatengera pafupifupi 300 ms kukonza wogwiritsa ntchito m'modzi, ndiye kwa onse ogwiritsa ntchito ili kale sekondi; nthawi yomwe imagwiritsidwa ntchito motsatana imadalira kuchuluka kwa ogwiritsa ntchito. Koma popeza kupeza kuchuluka kwa repo sikudalirana, njirazo zitha kufananizidwa. Izi zimafuna kugwira ntchito ndi .map ndi Promise.all: