Ha re shebeng Async/Await ho JavaScript re sebelisa mehlala

Sengoli sa sengoloa se hlahloba mehlala ea Async / Await ho JavaScript. Ka kakaretso, Async/Await ke mokhoa o bonolo oa ho ngola khoutu e sa lumellaneng. Pele tšobotsi ena e hlaha, khoutu e joalo e ne e ngoloa ho sebelisoa li-callback le litšepiso. Sengoli sa sengoloa sa mantlha se senola melemo ea Async / Emela ka ho sekaseka mehlala e fapaneng.

Re hopotsa: bakeng sa babali bohle ba "Habr" - theolelo ea li-ruble tse 10 ha u ngolisa thupelong efe kapa efe ea Skillbox u sebelisa khoutu ea papatso ea "Habr".

Skillbox e khothaletsa: Lithuto tsa inthaneteng "Moetsi oa Java".

hore o letsetswe

Callback ke ts'ebetso eo mohala oa eona o liehang ho fihlela nako e sa lekanyetsoang. Nakong e fetileng, li-callback li ne li sebelisoa libakeng tseo tsa khoutu moo sephetho se neng se ke ke sa fumanoa hang-hang.

Mona ke mohlala oa ho bala faele ka mokhoa o sa tsitsang ho Node.js:

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

Mathata a hlaha ha o hloka ho etsa ts'ebetso e 'maloa ea asynchronous hang-hang. Ha re nahane ka boemo bona: kopo e etsoa ho database ea basebelisi ba Arfat, o hloka ho bala profil_img_url ea eona mme o khoasolle setšoantšo ho tsoa ho seva sa someserver.com.
Ka mor'a ho kopitsa, re fetolela setšoantšo ho sebopeho se seng, mohlala ho tloha PNG ho ea JPEG. Haeba phetoho e atlehile, lengolo le romelloa ho lengolo-tsoibila la mosebelisi. Ka mor'a moo, tlhahisoleseding e mabapi le ketsahalo e kenngoa faeleng ea transformations.log, e bontšang letsatsi.

Ke habohlokoa ho ela hloko ho kopana ha li-callbacks le palo e kholo ea }) karolong ea ho qetela ea khoutu. E bitsoa Callback Hell kapa Pyramid of Doom.

Melemo ea mokhoa ona e totobetse:

  • Khoutu ena e thata ho e bala.
  • Hape ho thata ho sebetsana le liphoso, tseo hangata li lebisang ho boleng bo tlase ba khoutu.

Ho rarolla bothata bona, litšepiso li ile tsa eketsoa ho JavaScript. Li u lumella ho nkela sebaka se tebileng sa nesting ea callbacks ka lentsoe .then.

Karolo e ntle ea litšepiso ke hore li etsa hore khoutu e balehe hamolemo, ho tloha holimo ho ea tlase ho e-na le ho tloha ho le letšehali ho ea ho le letona. Leha ho le joalo, litšepiso le tsona li na le mathata a tsona:

  • U hloka ho eketsa tse ngata .ka nako eo.
  • Sebakeng sa leka/tshwara, .catch e sebedisetswa ho sebetsana le diphoso tsohle.
  • Ho sebetsa ka litšepiso tse ngata ka har'a loop e le 'ngoe ha ho bonolo kamehla; maemong a mang, ba thatafatsa khoutu.

Mona ke bothata bo tla bontša moelelo oa ntlha ea ho qetela.

Ha re re re na le for lupu e hatisang tatellano ea linomoro ho tloha ho 0 ho isa ho 10 ka linako tse sa reroang (metsotsoana e 0–n). U sebelisa litšepiso, u hloka ho fetola loop ena e le hore linomoro li hatisoe ka tatellano ho tloha ho 0 ho ea ho 10. Kahoo, haeba ho nka metsotsoana e 6 ho hatisa zero le metsotsoana e 2 ho hatisa e le 'ngoe, zero e lokela ho hatisoa pele, ebe joale. nako ea ho bala ea ho hatisa e tla qala.

'Me ha e le hantle, ha re sebelise Async/Await kapa .sort ho rarolla bothata bona. Tharollo ea mohlala e qetellong.

Mesebetsi ea Async

Keketso ea mesebetsi ea async ho ES2017 (ES8) e nolofalitse mosebetsi oa ho sebetsa ka litšepiso. Kea hlokomela hore mesebetsi ea async e sebetsa "ka holim'a" litšepiso. Mesebetsi ena ha e emele maikutlo a fapaneng ka boleng. Mesebetsi ea Async e etselitsoe ho fapana le khoutu e sebelisang litšepiso.

Async/Await e etsa hore ho khonehe ho hlophisa mosebetsi ka khoutu e sa lumellaneng ka mokhoa o lumellanang.

Kahoo, ho tseba litšepiso ho etsa hore ho be bonolo ho utloisisa melao-motheo ea Async / Await.

hokahanngoang

Ka tloaelo e na le mantsoe a mabeli a bohlokoa: async le emetse. Lentsoe la pele le fetola tšebetso hore e be asynchronous. Mesebetsi e joalo e lumella tšebeliso ea ho leta. Boemong bofe kapa bofe, ho sebelisa ts'ebetso ena ho tla hlahisa phoso.

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

Async e kentsoe qalong ea phatlalatso ea tšebetso, 'me tabeng ea ho sebetsa ha motsu, pakeng tsa letšoao la "=" le masakaneng.

Mesebetsi ena e ka behoa nthong e le mekhoa kapa ea sebelisoa ho phatlalatso ea sehlopha.

// 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! Ke habohlokoa ho hopola hore lihahi tsa lihlopha le li-getters / li-setter li ke ke tsa lumellana.

Semantics le melao ea ho phethahatsa

Mesebetsi ea Async ha e le hantle e tšoana le mesebetsi e tloaelehileng ea JS, empa ho na le mekhelo.

Kahoo, mesebetsi ea async e lula e khutlisa litšepiso:

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

Ka ho khetheha, fn e khutlisetsa khoele hello. Hantle, kaha sena ke ts'ebetso ea asynchronous, boleng ba khoele bo phuthetsoe ka tšepiso e sebelisang sehahi.

Mona ke moralo o mong ntle le Async:

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

Tabeng ena, tšepiso e khutlisetsoa "ka letsoho". Mosebetsi oa asynchronous o lula o phuthetsoe ka tšepiso e ncha.

Haeba boleng ba ho khutla e le ba khale, mosebetsi oa async o khutlisa boleng ka ho bo phuthela ka tšepiso. Haeba boleng ba ho khutlisa e le ntho ea tšepiso, tharollo ea eona e khutlisetsoa tšepisong e ncha.

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

Empa ho etsahala'ng haeba ho na le phoso ka har'a ts'ebetso ea asynchronous?

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

Haeba e sa sebetsoe, foo() e tla khutlisa tšepiso ka ho hana. Boemong bona, Tshepisa.hana e nang le phoso e tla kgutlisetswa sebakeng sa Tshepiso.rarolla.

Mesebetsi ea Async e lula e hlahisa tšepiso, ho sa tsotellehe hore na ho khutlisetsoa eng.

Mesebetsi ea Asynchronous e ema nako le nako ha e letetsoe.

Ho emela ho ama lipolelo. Kahoo, haeba polelo e le tšepiso, mosebetsi oa async o emisoa ho fihlela tšepiso e phethahala. Haeba poleloana e se ts'episo, e fetoloa ts'episong ka Ts'episo.rarolla ebe e phethoa.

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

Mona ke tlhaloso ea hore na fn function e sebetsa joang.

  • Ka mor'a ho e bitsa, mohala oa pele o fetoloa ho tloha const a = emela 9; in const a = emela Tšepiso.rarolla(9);.
  • Kamora ho sebelisa Emela, ts'ebetso ea ts'ebetso e emisoa ho fihlela a e fumana boleng ba eona (maemong a hajoale ke 9).
  • delayAndGetRandom(1000) e emisa ts'ebetso ea fn ho fihlela e phethela (kamora motsotsoana o le mong). Sena se emisa hantle ts'ebetso ea fn bakeng sa motsotsoana o le mong.
  • delayAndGetRandom(1000) ka resolution e khutlisa boleng bo sa reroang, bo abeloang mofuta oa b.
  • Hantle, nyeoe e nang le feto-fetoha c e tšoana le nyeoe ea ho feto-fetoha a. Kamora moo, ntho e ngoe le e ngoe e ema motsotsoana, empa joale delayAndGetRandom(1000) ha e khutlise letho hobane ha e hlokehe.
  • Ka lebaka leo, litekanyetso li baloa ho sebelisoa foromo a + b * c. Sephetho se phuthetsoe ka tšepiso e sebelisang Tšepiso.rarolla le ho khutlisetsoa ke mosebetsi.

Likhefutso tsena li ka re hopotsa lijenereithara ho ES6, empa ho na le ho hong ho eona mabaka a hao.

Ho rarolla bothata

Joale, a re shebeng tharollo ea bothata bo boletsoeng ka holimo.

Mosebetsi oa finishMyTask o sebelisa Await ho emela liphetho tsa ts'ebetso tse kang queryDatabase, sendEmail, logTaskInFile, le tse ling. Haeba u bapisa tharollo ena le eo ho eona litšepiso li ileng tsa sebelisoa, ho tšoana ho tla totobala. Leha ho le joalo, mofuta oa Async/Await o nolofatsa mathata ohle a syntactic haholo. Tabeng ena, ha ho na palo e kholo ea li-callback le liketane tse kang .then/.catch.

Mona ke tharollo ka tlhahiso ea linomoro, ho na le likhetho tse peli.

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

'Me mona ke tharollo e sebelisang mesebetsi ea async.

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

Phoso ea ho sebetsa

Liphoso tse sa sebetsanoeng li phuthetsoe ka tšepiso e lahliloeng. Leha ho le joalo, mesebetsi ea async e ka sebelisa try/catch ho sebetsana le liphoso ka tumellano.

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() ke ts'ebetso e ts'oanang e ka atlehang ("nomoro e phethahetseng") kapa e hlolehang ka phoso ("Tšoarelo, palo e kholo haholo").

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

Kaha mohlala o ka holimo o lebeletse hore canRejectOrReturn e phethahale, ho hlōleha ha eona ho tla fella ka ho etsoa ha thibelo ea ho tšoasa. Ka lebaka leo, foofo e tla qetella e se e sa hlalosoang (ha ho se letho le khutlisoang lebaleng la teko) kapa ka phoso e fumanoeng. Ka lebaka leo, ts'ebetso ena e ke ke ea hloleha hobane teko/tšoasa e tla sebetsana le tšebetso foo ka boeona.

Mohlala o mong ke ona:

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

Ho bohlokoa ho ela hloko taba ea hore ka mohlala, canRejectOrReturn e khutlisoa ho tsoa foo. Foo tabeng ena e fela ka nomoro e phethahetseng kapa e khutlisa Phoso ("Tšoarelo, palo e kholo haholo"). Sebaka sa ho tšoasa se ke ke sa etsoa.

Bothata ke hore foo e khutlisa tšepiso e fetisitsoeng ho canRejectOrReturn. Kahoo tharollo ea foo e fetoha tharollo ea canRejectOrReturn. Tabeng ena, khoutu e tla ba le mela e 'meli feela:

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

Mona ke se etsahalang haeba u sebelisa await le ho khutla hammoho:

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

Khoutung e kaholimo, foo e tla tsoa ka katleho ka palo e phethahetseng le phoso e ts'oaroang. Ha ho na ho hana mona. Empa foo e tla khutla ka canRejectOrReturn, eseng e sa hlalosoang. Ha re etse bonnete ba sena ka ho tlosa mohala oa ho letsetsa canRejectOrReturn():

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

Liphoso tse tloaelehileng le maraba

Maemong a mang, ho sebelisa Async / Await ho ka baka liphoso.

Lebala leta

Sena se etsahala hangata - lebitso la sehlooho le lebetsoeng le lebetsoe pele ho tšepiso:

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

Joalokaha u bona, ha ho na ho emela kapa ho khutla ka khoutu. Ka hona foo kamehla e tsoa e sa hlalosoa ntle le tieho ea motsotsoana o le mong. Empa tšepiso e tla phethahala. Haeba e lahlela phoso kapa ho hana, joale UnhandledPromiseRejectionWarning e tla bitsoa.

Mesebetsi ea Async ho Li-callbacks

Lisebelisoa tsa Async li sebelisoa hangata ho .map kapa .filter joalo ka li-callbacks. Mohlala ke ts'ebetso ea fetchPublicReposCount(username), e khutlisetsang palo ea lipolokelo tse bulehileng ho GitHub. Ha re re ho na le basebelisi ba bararo bao re hlokang metrics ea bona. Mona ke khoutu ea mosebetsi ona:

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

Re hloka li-account tsa ArfatSalman, octocat, norvig. Tabeng ena re etsa:

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

Ho bohlokoa ho ela hloko Leta ho .map callback. Mona lipalo ke letoto la litšepiso, 'me .map ke pitso e sa tsejoeng bakeng sa mosebelisi e mong le e mong ea boletsoeng.

Tšebeliso e feteletseng ea ho leta

Ha re nke khoutu ena e le mohlala:

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

Mona nomoro ea repo e behiloe ka har'a phapang ea palo, ebe palo ena e kenyelletsoa lethathamong la lipalo. Bothata ba khoutu ke hore ho fihlela data ea mosebelisi oa pele e fihla ho tsoa ho seva, basebelisi bohle ba latelang ba tla be ba le maemong a standby. Ka hona, mosebelisi a le mong feela o sebetsoa ka nako.

Haeba, ka mohlala, ho nka hoo e ka bang 300 ms ho sebetsa mosebelisi a le mong, joale ho basebelisi bohle e se e le motsotsoana; nako e sebelisitsoeng ka mokhoa o ikhethileng e ipapisitse le palo ea basebelisi. Empa kaha ho fumana palo ea repo ha ho itšetlehe ka e mong, lits'ebetso li ka bapisoa. Sena se hloka ho sebetsa le .map le Promise.all:

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

Tšepisa.bohle ba fumana letoto la ditshepiso e le kenyeletso mme ba kgutlisa tshepiso. Ea ho qetela, ka mor'a hore litšepiso tsohle tse lethathamong li phethiloe kapa ka lekhetlo la pele la ho hanoa, li phethetsoe. Ho ka etsahala hore kaofela ha bona ba se ke ba qala ka nako e le 'ngoe - molemong oa ho etsa bonnete ba ho qala ka nako e le ngoe, o ka sebelisa p-mapa.

fihlela qeto e

Mesebetsi ea Async e ntse e ba bohlokoa haholo bakeng sa nts'etsopele. Hantle, bakeng sa ts'ebeliso e lumellanang ea mesebetsi ea async, u lokela ho e sebelisa Async Iterators. Moqapi oa JavaScript o lokela ho tseba sena hantle.

Skillbox e khothaletsa:

Source: www.habr.com

Eketsa ka tlhaloso