Me titiro ki Async/Await i JavaScript ma te whakamahi tauira

Ka tirohia e te kaituhi o te tuhinga nga tauira o Async/Await in JavaScript. I te katoa, ko Async/Await he huarahi watea ki te tuhi waehere tukutahi. I mua i te putanga mai o tenei ahuatanga, i tuhia taua waehere ma te whakamahi i nga waea whakahoki me nga oati. Ko te kaituhi o te tuhinga taketake e whakaatu ana i nga painga o Async/Await ma te tātari i nga tauira rereke.

Ka whakamahara matou: mo nga kaipānui katoa o "Habr" - he utu mo te 10 rubles i te wa e whakauru ana ki tetahi akoranga Skillbox ma te whakamahi i te waehere whakatairanga "Habr".

Ka tūtohu a Skillbox: Matauranga ipurangi "Kaiwhakawhanake Java".

hokiwaea

Ko te Waea Whakahoki he mahi kua whakaroa te waea mo nga wa katoa. I mua, i whakamahia nga waea hoki ki era waahi o te waehere kaore e taea te whiwhi i nga hua i te wa tonu.

Anei tetahi tauira o te panui tukutahi i tetahi konae kei Node.js:

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

Ka puta ake nga raru ina hiahia koe ki te mahi i nga mahi tukutahi i te wa kotahi. Whakaarohia tenei ahuatanga: ka tukuna he tono ki te papaa raraunga kaiwhakamahi Arfat, me panui koe i tana mara profile_img_url me te tango whakaahua mai i te server someserver.com.
I muri i te tango, ka hurihia e matou te ahua ki tetahi atu whakatakotoranga, hei tauira mai i PNG ki JPEG. Mena i angitu te huringa, ka tukuna he reta ki te imeera a te kaiwhakamahi. I muri mai, ka whakauruhia nga korero mo te huihuinga ki te konae transformations.log, e tohu ana i te ra.

He mea tika kia aro ki te inaki o nga waea hoki me te nui o te }) i te waahanga whakamutunga o te waehere. E kiia ana ko Callback Hell, Pyramid of Doom ranei.

Ka kitea nga huakore o tenei tikanga:

  • He uaua tenei waehere ki te panui.
  • He uaua hoki ki te hapai i nga hapa, he maha nga wa ka paheke te kounga o te waehere.

Hei whakaoti i tenei raru, i taapirihia nga kupu whakaari ki te JavaScript. Ka whakaaetia koe ki te whakakapi i te kohanga hohonu o nga waea hoki ki te kupu .katahi.

Ko te ahua pai o nga kupu oati he pai ake te panui o te waehere, mai i runga ki raro kaua mai i te maui ki te matau. Heoi ano, he raruraru ano nga kupu whakaari:

  • Me taapiri koe i te maha o .katahi.
  • Engari i te ngana/hopu, ka whakamahia te .catch ki te hapai i nga hapa katoa.
  • Ko te mahi me nga oati maha i roto i te kopae kotahi kaore i te watea i nga wa katoa; i etahi wa, ka whakararu i te waehere.

Anei he raruraru ka whakaatu i te tikanga o te waahi whakamutunga.

Inaa he kapiti mo ta tatou e tarai ana i te raupapa tau mai i te 0 ki te 10 i nga waahi matapōkere (0–n hekona). Ma te whakamahi i nga kupu oati, me huri koe i tenei kohanga kia taia ai nga tau ki te raupapa mai i te 0 ki te 10. Na, ki te 6 hēkona te roa ki te tā i te kore me te 2 hēkona ki te tā i te kotahi, me taia te kore i te tuatahi, katahi ka ka timata te kaute mo te ta i te kotahi.

A ko te tikanga, kaore matou e whakamahi i te Async/Await, .sort ranei hei whakaoti i tenei raru. He otinga tauira kei te mutunga.

Nga mahi Async

Ko te taapiri o nga mahi async i roto i te ES2017 (ES8) i ngawari te mahi ki te mahi me nga kupu whakaari. Ka kite ahau kei te mahi nga mahi async "i runga" o nga kupu whakaari. Karekau enei mahi e whakaatu ana i nga ariā rereke. Ko nga mahi Async he rereke ki te waehere e whakamahi ana i nga kupu whakaari.

Ka taea e Async/Await te whakarite mahi me te waehere tukutahi i roto i te ahua tukutahi.

No reira, ma te mohio ki nga oati ka ngawari ake te maarama ki nga maataapono o Async/Await.

wetereo

Ko te tikanga e rua nga kupu matua: async me te tatari. Ko te kupu tuatahi ka huri te mahi ki te tukutahi. Ko enei mahi ka taea te whakamahi i te tatari. I tetahi atu take, ma te whakamahi i tenei mahi ka puta he hapa.

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

Ka whakauruhia a Async i te timatanga o te whakapuakanga mahi, me te ahuatanga o te mahi pere, i waenga i te tohu "=" me nga reu.

Ka taea te whakanoho i enei mahi ki roto i tetahi mea hei tikanga, hei whakamahi ranei i roto i te whakapuakanga a te karaehe.

// 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! He mea tika kia maumahara kaore e taea e nga kaihanga akomanga me nga kaiwhakatakoto whakaaro te tukutahi.

Tikanga me nga ture mahi

He rite tonu nga mahi Async ki nga mahi JS paerewa, engari he rereke.

Na, ko nga mahi async ka whakahoki i nga kupu whakaari:

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

Ina koa, ka whakahokia e fn te aho kia ora. Ana, i te mea he mahi tukutahi tenei, ka takai te uara aho ki roto i te oati ma te whakamahi i te kaihanga.

Anei tetahi hoahoa rereke kaore he Async:

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

I tenei keehi, ka whakahokia te kupu whakaari "ma te ringa". Ko te mahi tukutahi ka takai ki tetahi kupu whakaari hou.

Mena he mea taketake te uara whakahoki, ka whakahokia e te mahi async te uara ma te takai i roto i te oati. Mena he mea oati te uara whakahoki, ka whakahokia mai tana whakatau ki tetahi oati hou.

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

Engari ka aha mena he hapa kei roto i tetahi mahi tukutahi?

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

Ki te kore e tukatukahia, ka whakahokia e foo() he kupu taurangi me te whakakore. I tenei ahuatanga, Promise.reject kei roto he hapa ka whakahokia hei utu mo Promise.resolve.

Ko nga mahi a Async i nga wa katoa ka whakaputa i te oati, ahakoa he aha te mea ka whakahokia mai.

Ka okioki nga mahi tukutahi i ia tatari.

Ka pa ki nga korero a Tatari. Na, mena he kupu oati te korero, ka whakatarewahia te mahi async kia tutuki ra ano te oati. Mēnā ehara te kīanga i te kupu oati, ka hurihia ki te kupu oati mā Promise.resolve ka oti.

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

Anei he whakaahuatanga mo te mahi a te mahi fn.

  • Whai muri i te karanga, ka hurihia te rarangi tuatahi mai i te const a = tatari 9; in const a = tatari Whakataunga.resolve(9);.
  • Whai muri i te whakamahi i te Await, ka whakatarewahia te mahinga mahi kia tae ra ano te uara (i te ahuatanga o naianei ko te 9).
  • delayAndGetRandom(1000) ka whakatā i te mahinga o te mahi fn kia oti ra ano (i muri i te 1 hēkona). Ka mutu te mahi fn mo te 1 hēkona.
  • delayAndGetRandom(1000) mā te whakatau ka whakahokia he uara matapōkere, ka tautapa ki te taurangi b.
  • Kaati, he rite te keehi ki te taurangi c ki te keehi me te taurangi a. Whai muri i tera, ka mutu nga mea katoa mo te tuarua, engari inaianei ko delayAndGetRandom(1000) karekau he whakahoki na te mea kaore e hiahiatia.
  • Ko te mutunga, ka tatauhia nga uara ma te whakamahi i te tauira a + b * c. Ko te hua ka takai ki te kupu whakaari ma te whakamahi i te Promise.resolve ka whakahokia mai e te mahi.

Ko enei okiokinga ka maumahara pea ki nga kaihanga i roto i te ES6, engari he mea ano o koutou take.

Te whakaoti rapanga

Kaati, inaianei ka titiro tatou ki te otinga o te raruraru kua whakahuatia ake nei.

Ka whakamahi te mahi whakaotiMyTask Await ki te tatari mo nga hua o nga mahi penei i te queryDatabase, sendEmail, logTaskInFile, me etahi atu. Mena ka whakatauritea e koe tenei otinga ki tera i whakamahia nga kupu whakaari, ka kitea nga ritenga. Heoi, ko te putanga Async/Await he tino whakangwari i nga uauatanga wetereo katoa. I tenei keehi, kaore he maha o nga waea whakahoki me nga mekameka penei i te .then/.catch.

Anei he otinga me te putanga o nga tau, e rua nga whiringa.

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

Anei he otinga ma te whakamahi i nga mahi async.

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

Hapa tukatuka

Ko nga hapa kaore i whakahaeretia ka takaia ki te oati kua paopaohia. Heoi, ka taea e nga mahi async te whakamahi i te ngana/hopu hei hapai i nga hapa i te wa kotahi.

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() he mahi tukutahi ka angitu (“tau tino tika”) ka taka ranei ki te hapa (“Aroha mai, he nui rawa te nama”).

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

I te mea ko te tauira i runga ake nei e tumanako ana ka taea e RejectOrReturn te mahi, ko tana korenga ka puta te mahi o te poraka hopu. Ko te mutunga mai, ka mutu te mahi foo me te kore tautuhia (kaore he mea i whakahokia mai i te paraka whakamatau) me te hapa ranei i mau. Ko te mutunga mai, e kore tenei mahi e taka na te mea ma te ngana/hopu ka hapai i te mahi foo ake.

Anei ano tetahi tauira:

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

He pai ki te aro ki te meka i roto i te tauira, canRejectOrReturn kua whakahokia mai i te foo. Ko te Foo i tenei keehi ka mutu me te tau tino tika ka whakahoki mai ranei he Hapa ("Aroha mai, he nui rawa te nama"). Ko te poraka hopu e kore rawa e mahia.

Ko te raru ka whakahokia e foo te kupu whakaari i tukuna mai i canRejectOrReturn. Na ko te otinga ki te foo ka waiho hei otinga ki te canRejectOrReturn. I tenei take, ka rua noa nga rarangi o te waehere:

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

Anei te aha mena ka whakamahi koe i te tatari me te hoki tahi:

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

I roto i te waehere i runga ake nei, ka puta angitu a foo me te tau tino tika me te hapa i mau. Karekau he whakakore i konei. Engari ka hoki mai a foo me te canRejectOrReturn, ehara i te mea kaore i tautuhia. Me whakarite tenei ma te tango i te hokinga tatari canRejectOrReturn() raina:

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

Nga hapa noa me nga mahanga

I etahi wa, ma te whakamahi i te Async/Await ka puta he hapa.

Kua warewaretia te tatari

He maha nga wa ka puta - kua warewarehia te kupu matua tatari i mua i te oati:

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

Ka kite koe, kaore he tatari, ka hoki mai ranei i roto i te waehere. Na reira ka puta tonu a foo me te kore tautuhi me te kore e roa te 1 tuarua. Engari ka tutuki te kupu whakaari. Mena ka puta he hapa, he whakakore ranei, ka karangahia te UnhandledPromiseRejectionWarning.

Nga Mahi Async i nga Waea Whakahoki

He maha nga wa e whakamahia ana nga mahi Async i roto i te .map, i te .filter ranei hei whakahoki waea. He tauira ko te mahi fetchPublicReposCount(ingoakaiwhakamahi), e whakahoki ana i te maha o nga putunga tuwhera i runga i GitHub. Me kii e toru nga kaiwhakamahi e hiahiatia ana e taatau inenga. Anei te waehere mo tenei mahi:

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

Kei te hiahia matou ki nga kaute ArfatSalman, octocat, norvig. I tenei keehi ka mahia e matou:

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

He mea tika kia aro ki te Tatari i te .map hoki waea. He maha nga kupu oati kei konei, a ko te .mahere he waea whakahoki ingoamuna mo ia kaiwhakamahi kua tohua.

Ko te whakamahi tonu o te tatari

Me tango tenei waehere hei tauira:

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

I konei ka whakauruhia te tau repo ki te taurangi tatau, katahi ka taapirihia tenei nama ki te rarangi tatau. Ko te raru o te waehere kia tae mai ra ano nga raraunga a te kaiwhakamahi tuatahi mai i te tūmau, ka noho nga kaiwhakamahi katoa i muri mai i te aratau tatari. No reira, kotahi anake te kaiwhakamahi ka tukatukahia i te wa kotahi.

Mena, hei tauira, tata ki te 300 ms ki te whakahaere i te kaiwhakamahi kotahi, na mo nga kaiwhakamahi katoa he tuarua kee; ko te wa e pau ana i runga i te rarangi ka whakawhirinaki ki te maha o nga kaiwhakamahi. Engari i te mea ko te whiwhi i te maha o nga repo kaore i te whakawhirinaki tetahi ki tetahi, ka taea te whakarara nga tukanga. Me mahi tahi me .map me Promise.all:

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

Ka whiwhi a Promise.all i te maha o nga kupu taurangi hei whakaurunga me te whakahoki kupu oati. Ko te whakamutunga, i muri i nga oati katoa i roto i te rarangi kua oti, i te whakakorenga tuatahi ranei, kua oti. Tera pea karekau ratou katoa e timata i te wa kotahi - kia pai ai te tiimata i te wa kotahi, ka taea e koe te whakamahi mapi-p.

mutunga

Ko nga mahi Async kei te piki haere te hiranga mo te whanaketanga. Ana, mo te whakamahi urutau o nga mahi async, me whakamahi koe Async Iterators. Ko te kaiwhakawhanake JavaScript me tino mohio ki tenei.

Ka tūtohu a Skillbox:

Source: will.com

Tāpiri i te kōrero