Ka anyị lee Async/Chere na Javascript site na iji atụ

Onye edemede edemede ahụ na-enyocha ihe atụ nke Async/Await na Javascript. N'ozuzu, Async/Await bụ ụzọ dabara adaba iji dee koodu asynchronous. Tupu njirimara a apụta, edere ụdị koodu ahụ site na iji oku azụghachi na nkwa. Onye dere edemede mbụ na-ekpughe uru nke Async/Await site n'ịtụle ihe atụ dị iche iche.

Anyị na -echetara: maka ndị na-agụ Habr niile - ego 10 ruble mgbe ị na-edebanye aha na nkuzi Skillbox ọ bụla site na iji koodu mgbasa ozi Habr.

Skillbox na-atụ aro: Usoro nkuzi n'ịntanetị "Onye nrụpụta Java".

callback

Nkpọghachi oku bụ ọrụ nke oku na-egbu oge ruo mgbe ebighị ebi. Na mbụ, a na-eji azụghachi oku na mpaghara koodu ebe enweghị ike nweta nsonaazụ ozugbo.

Nke a bụ ọmụmaatụ ịgụ faịlụ na-ejikọtaghị ọnụ na Node.js:

fs.readFile(__filename, 'utf-8', (err, data) => {
  if (err) {
    throw err;
  }
  console.log(data);
});

Nsogbu na-ebilite mgbe ịchọrọ ịme ọtụtụ ọrụ asynchronous n'otu oge. Ka anyị chee echiche nke a: Arịrịọ a rịọrọ na nchekwa data onye ọrụ Arfat, ịkwesịrị ịgụ ebe profaịlụ_img_url ya wee budata onyonyo sitere na sava someserver.com.
Mgbe nbudata, anyị na-atụgharị oyiyi ahụ na usoro ọzọ, dịka ọmụmaatụ site na PNG gaa na JPEG. Ọ bụrụ na ntụgharị ahụ gara nke ọma, a na-ezigara akwụkwọ ozi na email onye ọrụ. Na-esote, a na-abanye ozi gbasara ihe omume ahụ na faịlụ transformations.log, na-egosi ụbọchị.

Ọ bara uru ịṅa ntị na nchikota nke callbacks na ọnụ ọgụgụ buru ibu nke }) na akụkụ ikpeazụ nke koodu ahụ. A na-akpọ ya Callback hell ma ọ bụ Pyramid nke mbibi.

Ọdịmma nke usoro a doro anya:

  • Koodu a siri ike ịgụ.
  • Ọ na-esikwa ike ijikwa njehie, nke na-ebutekarị àgwà koodu adịghị mma.

Iji dozie nsogbu a, agbakwunyere nkwa na Javascript. Ha na-enye gị ohere iji okwu ahụ dochie nesting miri emi nke callbacks.

Akụkụ dị mma nke nkwa bụ na ha na-eme ka koodu ahụ dịkwuo mma nke ọma, site n'elu ruo na ala karịa site n'aka ekpe gaa n'aka nri. Agbanyeghị, nkwa nwekwara nsogbu ha:

  • Ikwesiri itinye otutu .mgbe ahu.
  • Kama ịnwa/ ijide, .catch na-eji edozi njehie niile.
  • Ịrụ ọrụ na ọtụtụ nkwa n'ime otu loop anaghị adị mma mgbe niile; n'ọnọdụ ụfọdụ, ha na-akpaghasị koodu ahụ.

Nke a bụ nsogbu nke ga-egosi ihe isi ihe ikpeazụ pụtara.

Ka e were ya na anyị nwere maka loop nke na-ebipụta usoro ọnụọgụgụ site na 0 ruo 10 na nkeji oge (0–n sekọnd). Iji nkwa, ịkwesịrị ịgbanwe loop a ka a na-ebipụta nọmba n'usoro site na 0 ruo 10. Ya mere, ọ bụrụ na ọ na-ewe 6 sekọnd iji bipụta efu na 2 sekọnd iji bipụta otu, efu kwesịrị ibipụta mbụ, wee bipụta ya. a ga-amalite ịgụta ọnụ maka ibipụta nke ahụ.

Ma n'ezie, anyị anaghị eji Async/Await ma ọ bụ .sort dozie nsogbu a. Ihe ngwọta ihe atụ dị na njedebe.

Async ọrụ

Mgbakwunye nke ọrụ async na ES2017 (ES8) mere ka ọrụ nke ịrụ ọrụ na nkwa dị mfe. Achọpụtara m na ọrụ async na-arụ ọrụ "n'elu" nke nkwa. Ọrụ ndị a anaghị anọchi anya echiche dị iche iche nke ọma. Ezubere ọrụ Async ka ọ bụrụ koodu ọzọ na-eji nkwa.

Async/Await na-eme ka o kwe omume ịhazi ọrụ na koodu asynchronous n'ụdị mmekọrịta.

Ya mere, ịmara nkwa na-eme ka ọ dịkwuo mfe ịghọta ụkpụrụ nke Async/Await.

syntax

Ọ na-enwekarị mkpụrụokwu abụọ: async na chere. Okwu mbụ na-atụgharị ọrụ ka ọ bụrụ asynchronous. Ọrụ ndị dị otú ahụ na-enye ohere iji ichere. N'ọnọdụ ọ bụla ọzọ, iji ọrụ a ga-ebute njehie.

// With function declaration
 
async function myFn() {
  // await ...
}
 
// With arrow function
 
const myFn = async () => {
  // await ...
}
 
function myFn() {
  // await fn(); (Syntax Error since no async)
}
 

A na-etinye Async na mmalite nke nkwupụta ọrụ ahụ, na n'ihe gbasara ọrụ akụ, n'etiti akara "=" na akara aka.

Enwere ike idobe ọrụ ndị a n'ime ihe dịka ụzọ ma ọ bụ jiri na nkwupụta klaasị.

// 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! Ọ dị mma icheta na ndị na-ewu klaasị na ndị na-eme ihe/setịta enweghị ike ịbụ asynchronous.

Semantics na iwu igbu

Ọrụ Async yiri ọrụ JS ọkọlọtọ, mana enwere ndị ọzọ.

Yabụ, ọrụ async na-eweghachi nkwa mgbe niile:

async function fn() {
  return 'hello';
}
fn().then(console.log)
// hello

Kpọmkwem, fn na-eweghachi eriri ndewo. Ọfọn, ebe ọ bụ na nke a bụ ọrụ asynchronous, uru eriri na-ejikọta ya na nkwa site na iji ihe nrụpụta.

Nke a bụ atụmatụ ọzọ na-enweghị Async:

function fn() {
  return Promise.resolve('hello');
}
 
fn().then(console.log);
// hello

N'okwu a, a na-eweghachi nkwa ahụ "aka". Ọrụ asynchronous na-etinye mgbe niile na nkwa ọhụrụ.

Ọ bụrụ na uru nlọghachi bụ ihe ochie, ọrụ async na-eweghachi uru ahụ site n'itinye ya na nkwa. Ọ bụrụ na uru nlọghachi bụ ihe nkwa, a na-eweghachi mkpebi ya na nkwa ọhụrụ.

const p = Promise.resolve('hello')
p instanceof Promise;
// true
 
Promise.resolve(p) === p;
// true
 

Mana gịnị ga - eme ma ọ bụrụ na enwere mperi n'ime ọrụ asynchronous?

async function foo() {
  throw Error('bar');
}
 
foo().catch(console.log);

Ọ bụrụ na ahazighị ya, foo() ga-eweghachi nkwa na ịjụ. N'ọnọdụ a, Nkwa.reject nwere njehie ga-eweghachite kama nkwa.resolve.

Ọrụ Async na-arụpụta nkwa mgbe niile, n'agbanyeghị ihe eweghachiri.

Ọrụ asynchronous kwụsịtụrụ na nchere ọ bụla.

Chere na-emetụta okwu. Ya mere, ọ bụrụ na okwu ahụ bụ nkwa, a na-akwụsị ọrụ async ruo mgbe e mezuru nkwa ahụ. Ọ bụrụ na okwu ahụ abụghị nkwa, a na-atụgharị ya na nkwa site na Promise.resolve wee mechaa ya.

// 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);

Na ebe a bụ nkọwa nke ka fn si arụ ọrụ.

  • Mgbe akpọchara ya, a na-atụgharị ahịrị nke mbụ site na const a = chere 9; na const a = chere nkwa.resolve(9);.
  • Mgbe ijiri Await, a kwụsịtụrụ mmezu ọrụ ahụ ruo mgbe ọ nwetara uru ya (n'ọnọdụ dị ugbu a ọ bụ 9).
  • delayAndGetRandom(1000) kwụsịtụrụ mmezu nke fn ọrụ ruo mgbe ọ ga-emecha onwe ya (mgbe 1 sekọnd). Nke a na-akwụsị ọrụ fn nke ọma maka 1 sekọnd.
  • delayAndGetRandom(1000) site na mkpebi weghachiri uru na-enweghị usoro, nke ekenyeziri ya na mgbanwe b.
  • Ọfọn, ikpe nwere variable c yiri nke nwere mgbanwe a. Mgbe nke ahụ gasịrị, ihe niile na-akwụsị maka sekọnd, ma ugbu a, delayAndGetRandom(1000) na-alaghachighị ihe ọ bụla n'ihi na ọ dịghị mkpa.
  • N'ihi ya, a na-agbakọ ụkpụrụ ndị ahụ site na iji usoro a + b * c. A na-etinye nsonaazụ ya na nkwa site na iji Promise.resolve wee weghachite site na ọrụ ahụ.

Nkwụsịtụ ndị a nwere ike ịdị na-echetara ndị na-emepụta ọkụ na ES6, mana ọ nwere ihe na ya ihe kpatara ya.

Ịdozi nsogbu ahụ

Ọfọn, ugbu a, ka anyị leba anya na ngwọta nke nsogbu ahụ a kpọtụrụ aha n'elu.

Arụ ọrụ finishMyTask na-eji Chere chere nsonaazụ arụmọrụ dị ka queryDatabase, sendEmail, logTaskInFile, na ndị ọzọ. Ọ bụrụ na i jiri ihe ngwọta a tụnyere nke e ji nkwa, myirịta ga-apụta ìhè. Agbanyeghị, ụdị Async/Await na-eme ka ihe mgbagwoju anya niile dị mfe. N'okwu a, ọ dịghị ọnụ ọgụgụ buru ibu nke callback na agbụ dị ka .mgbe ahụ / .catch.

Nke a bụ ihe ngwọta na mmepụta nke ọnụọgụgụ, enwere nhọrọ abụọ.

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);
    });
  });
};

Na ebe a bụ ngwọta site na iji ọrụ async.

async function printNumbersUsingAsync() {
  for (let i = 0; i < 10; i++) {
    await wait(i, Math.random() * 1000);
    console.log(i);
  }
}

Nhazi mperi

A na-ekechi njehie ndị a na-edozighị n'ime nkwa a jụrụ ajụ. Agbanyeghị, ọrụ async nwere ike iji nwaa/jide iji jikwaa njehie n'otu oge.

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() bụ ọrụ asynchronous nke na-aga nke ọma ("nọmba zuru oke") ma ọ bụ daa na mperi ("Ndo, ọnụọgụ buru ibu").

async function foo() {
  try {
    await canRejectOrReturn();
  } catch (e) {
    return 'error caught';
  }
}

Ebe ihe atụ dị n'elu na-atụ anya ka RejectOrReturn ga-emezu, ọdịda nke ya ga-eme ka e gbuo ngọngọ ahụ. N'ihi ya, foo ọrụ ga-ejedebe na enweghị nkọwa (mgbe ọ nweghị ihe eweghachiri na ngọngọ nnwale) ma ọ bụ na-ejide njehie. N'ihi nke a, ọrụ a agaghị ada n'ihi na ịnwale / ijide ga-ejikwa ọrụ foo n'onwe ya.

Nke a bụ ọmụmaatụ ọzọ:

async function foo() {
  try {
    return canRejectOrReturn();
  } catch (e) {
    return 'error caught';
  }
}

Ọ bara uru ịṅa ntị n'eziokwu ahụ na n'ihe atụ, canRejectOrReturn na-esi na foo laghachi. Foo n'okwu a ga-eji ọnụọgụ zuru oke kwụsị ma ọ bụ weghachi mperi ("Ndo, ọnụọgụ buru ibu"). Agaghị eme ihe mgbochi ahụ ma ọlị.

Nsogbu bụ na foo na-eweghachite nkwa e kwere na canRejectOrReturn. Ya mere, ngwọta maka foo na-aghọ ihe ngwọta maka rejectOrReturn. N'okwu a, koodu ahụ ga-enwe naanị ahịrị abụọ:

try {
    const promise = canRejectOrReturn();
    return promise;
}

Nke a bụ ihe na-eme ma ọ bụrụ na ị jiri chere wee laghachi ọnụ:

async function foo() {
  try {
    return await canRejectOrReturn();
  } catch (e) {
    return 'error caught';
  }
}

Na koodu dị n'elu, foo ga-apụ nke ọma yana ma ọnụọgụ zuru oke yana njehie ejidere. Agaghị enwe ọjụjụ ebe a. Mana foo ga-eji canRejectOrReturn laghachi, ọ bụghị na enweghị nkọwa. Ka anyị jide n'aka na nke a site n'iwepụ ahịrị nlọghachi echere nwere ikeRejectOrReturn():

try {
    const value = await canRejectOrReturn();
    return value;
}
// …

Ọtụtụ mmejọ na ọnyà

Mgbe ụfọdụ, iji Async/Await nwere ike bute mperi.

Echefuru echefu

Nke a na-eme ọtụtụ oge - echefuru okwu nchere tupu nkwa ahụ:

async function foo() {
  try {
    canRejectOrReturn();
  } catch (e) {
    return 'caught';
  }
}

Dịka ị na-ahụ, enweghị nchere ma ọ bụ nloghachi na koodu. Ya mere foo na-apụ mgbe niile na-akọwaghị ya na-enweghị igbu oge 1 sekọnd. Ma a ga-emezu nkwa ahụ. Ọ bụrụ na ọ tufuru mperi ma ọ bụ jụ, mgbe ahụ UnhandledPromiseRejectionWarning ga-akpọ.

Ọrụ Async na Callbacks

A na-ejikarị ọrụ Async eme ihe na .map ma ọ bụ .filter dị ka azụghachi azụ. Otu ihe atụ bụ ọrụ fetchPublicReposCount(aha njirimara), nke na-eweghachi ọnụọgụ ebe nchekwa mepere emepe na GitHub. Ka anyị kwuo na e nwere ndị ọrụ atọ anyị chọrọ metrik ha. Nke a bụ koodu maka ọrụ a:

const url = 'https://api.github.com/users';
 
// Utility fn to fetch repo counts
const fetchPublicReposCount = async (username) => {
  const response = await fetch(`${url}/${username}`);
  const json = await response.json();
  return json['public_repos'];
}

Anyị chọrọ ArfatSalman, octocat na akaụntụ norvig. N'okwu a, anyị na-eme:

const users = [
  'ArfatSalman',
  'octocat',
  'norvig'
];
 
const counts = users.map(async username => {
  const count = await fetchPublicReposCount(username);
  return count;
});

Ọ bara uru ịṅa ntị na Chere na .map callback. Ebe a na-agụta bụ ọtụtụ nkwa, na .map bụ azụghachị akpọghị aha maka onye ọrụ ọ bụla akọwapụtara.

Iji echere gabiga ókè

Ka anyị were koodu a dịka ọmụmaatụ:

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;
}

N'ebe a, a na-etinye nọmba repo na ọnụọgụ ọnụọgụ, mgbe ahụ, a na-agbakwunye nọmba a na nchịkọta ọnụ. Nsogbu dị na koodu ahụ bụ na ruo mgbe data onye ọrụ mbụ rutere na sava ahụ, ndị ọrụ niile na-esote ga-anọ na ọnọdụ njikere. Ya mere, ọ bụ naanị otu onye ọrụ ka a na-ahazi n'otu oge.

Ọ bụrụ na, dịka ọmụmaatụ, ọ na-ewe ihe dị ka 300 ms iji hazie otu onye ọrụ, mgbe ahụ maka ndị ọrụ niile ọ bụlarị nke abụọ; oge ejiri linearly dabere na ọnụ ọgụgụ ndị ọrụ. Ma ebe ọ bụ na ịnweta ọnụ ọgụgụ nke repo anaghị adabere na ibe ya, usoro ndị ahụ nwere ike ịmekọrịta. Nke a chọrọ iji .map na Promise.all rụọ ọrụ:

async function fetchAllCounts(users) {
  const promises = users.map(async username => {
    const count = await fetchPublicReposCount(username);
    return count;
  });
  return Promise.all(promises);
}

Nkwa.ha niile na-anata ọtụtụ nkwa dị ka ntinye na weghachi nkwa. Emechara nke ikpeazụ ka emechara nkwa niile dị n'usoro ma ọ bụ n'ajụjụ mbụ. Ọ nwere ike ime na ha niile anaghị ebido n'otu oge - iji hụ na mmalite n'otu oge, ịnwere ike iji p-map.

nkwubi

Ọrụ Async na-adịwanye mkpa maka mmepe. Ọ dị mma, maka iji mmegharị nke ọrụ async, ịkwesịrị iji Async Iterators. Onye nrụpụta Javascript kwesịrị ịma nke ọma na nke a.

Skillbox na-atụ aro:

isi: www.habr.com

Tinye a comment