E nānā iā Async/Await ma JavaScript me ka hoʻohana ʻana i nā laʻana
Nānā ka mea kākau o ka ʻatikala i nā hiʻohiʻona o Async/Await ma JavaScript. ʻO ka holoʻokoʻa, ʻo Async/Await kahi ala kūpono e kākau ai i ka code asynchronous. Ma mua o ka puka ʻana o kēia hiʻohiʻona, ua kākau ʻia kēlā code me ka hoʻohana ʻana i nā callbacks a me nā ʻōlelo hoʻohiki. Hōʻike ka mea kākau o ka ʻatikala kumu i nā pono o Async/Await ma ka nānā ʻana i nā hiʻohiʻona like ʻole.
Hoʻomaopopo mākou iā ʻoe:no ka poʻe heluhelu a pau o "Habr" - kahi ho'ēmi o 10 rubles i ka wā e kākau inoa ai i kekahi papa Skillbox e hoʻohana ana i ka code promotional "Habr".
ʻO ka Callback kahi hana i hoʻopaneʻe ʻia ke kelepona no ka manawa pau ʻole. Ma mua, ua hoʻohana ʻia nā kelepona i kēlā mau wahi o ke code kahi i hiki ʻole ke loaʻa koke ka hopena.
Eia kekahi laʻana o ka heluhelu asynchronously i kahi faila ma Node.js:
Piʻi ka pilikia inā pono ʻoe e hana i nā hana asynchronous i ka manawa hoʻokahi. E noʻonoʻo kākou i kēia hiʻohiʻona: ua noi ʻia i ka waihona mea hoʻohana Arfat, pono ʻoe e heluhelu i kāna kahua profile_img_url a hoʻoiho i kahi kiʻi mai ka server someserver.com.
Ma hope o ka hoʻoiho ʻana, hoʻololi mākou i ke kiʻi i kahi ʻano ʻē aʻe, no ka laʻana mai PNG a JPEG. Inā holomua ka hoʻololi ʻana, hoʻouna ʻia kahi leka i ka leka uila o ka mea hoʻohana. A laila, hoʻokomo ʻia ka ʻike e pili ana i ka hanana i ka faila transformations.log, e hōʻike ana i ka lā.
Pono e hoʻolohe i ka overlap o callbacks a me ka helu nui o }) ma ka hapa hope o ke code. Ua kapa ʻia ʻo Callback Hell a i ʻole Pyramid of Doom.
ʻIke ʻia nā hemahema o kēia ʻano:
He paʻakikī kēia code e heluhelu.
He mea paʻakikī hoʻi ka mālama ʻana i nā hewa, e alakaʻi pinepine ai i ka maikaʻi ʻole o ke code.
No ka hoʻoponopono ʻana i kēia pilikia, ua hoʻohui ʻia nā ʻōlelo hoʻohiki i JavaScript. Hāʻawi lākou iā ʻoe e hoʻololi i ka nesting hohonu o nā callbacks me ka huaʻōlelo .then.
ʻO ka hiʻohiʻona maikaʻi o nā ʻōlelo hoʻohiki, ʻoi aku ka maikaʻi o ka heluhelu ʻana i ke code, mai luna a lalo ma mua o ka hema a i ka ʻākau. Eia naʻe, loaʻa i nā ʻōlelo hoʻohiki ko lākou mau pilikia:
Pono ʻoe e hoʻohui i ka nui o .then.
Ma kahi o ka ho'āʻo/hopu, hoʻohana ʻia ʻo .catch e mālama i nā hewa āpau.
ʻAʻole maʻalahi ka hana ʻana me nā ʻōlelo hoʻohiki he nui i loko o ka loop hoʻokahi; i kekahi mau hihia, paʻakikī lākou i ke code.
Eia kekahi pilikia e hōʻike ana i ke ʻano o ka helu hope.
Inā paha he loop loop kā mākou e paʻi ana i ke kaʻina o nā helu mai ka 0 a hiki i ka 10 ma nā manawa āpau (0–n kekona). Me ka hoʻohana ʻana i nā ʻōlelo hoʻohiki, pono ʻoe e hoʻololi i kēia loop i paʻi ʻia nā helu ma ke kaʻina mai ka 0 a hiki i ka 10. No laila, inā 6 kekona e paʻi i kahi zero a me 2 kekona e paʻi i kahi, pono e paʻi mua ʻia ka zero, a laila e hoʻomaka ka helu ʻana no ka paʻi ʻana i ka mea.
A ʻoiaʻiʻo, ʻaʻole mākou e hoʻohana iā Async/Await a i ʻole .sort e hoʻoponopono i kēia pilikia. Aia kekahi laʻana hoʻonā ma ka hopena.
Nā hana Async
ʻO ka hoʻohui o nā hana async ma ES2017 (ES8) i maʻalahi i ka hana o ka hana me nā ʻōlelo hoʻohiki. ʻIke wau e hana ana nā hana async "ma luna" o nā ʻōlelo hoʻohiki. ʻAʻole hōʻike kēia mau hana i nā manaʻo like ʻole qualitatively. Hana ʻia nā hana Async ma ke ʻano he koho i ka code e hoʻohana ana i nā ʻōlelo hoʻohiki.
Hiki iā Async/Await ke hoʻonohonoho i ka hana me ka code asynchronous i kahi ʻano synchronous.
No laila, ʻo ka ʻike ʻana i nā ʻōlelo hoʻohiki e maʻalahi ka hoʻomaopopo ʻana i nā loina o Async/Await.
Ka Mooolelo O
ʻO ka maʻamau he mau huaʻōlelo ʻelua: async a kali. Hoʻololi ka huaʻōlelo mua i ka hana i asynchronous. Hāʻawi ia mau hana i ka hoʻohana ʻana i ka kali. Ma nā hihia ʻē aʻe, e hoʻohana ana kēia hana i kahi hewa.
// With function declaration
async function myFn() {
// await ...
}
// With arrow function
const myFn = async () => {
// await ...
}
function myFn() {
// await fn(); (Syntax Error since no async)
}
Hoʻokomo ʻia ʻo Async ma ka hoʻomaka ʻana o ka hoʻolaha hana, a ma ke ʻano o kahi hana pua, ma waena o ka hōʻailona "=" a me nā pale.
Hiki ke hoʻokomo ʻia kēia mau hana i loko o kahi mea ma ke ʻano he ʻano hana a i ʻole hoʻohana ʻia i loko o kahi haʻi papa.
// 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! Pono e hoʻomanaʻo ʻaʻole hiki i nā mea kūkulu papa a me nā getters/setters ke asynchronous.
Semantics a me nā lula hoʻokō
Ua like like nā hana Async me nā hana JS maʻamau, akā aia nā ʻokoʻa.
No laila, hoʻihoʻi mau nā hana async i nā ʻōlelo hoʻohiki:
async function fn() {
return 'hello';
}
fn().then(console.log)
// hello
ʻOiaʻiʻo, hoʻihoʻi ʻo fn i ke kaula aloha. ʻAe, no ka mea he hana asynchronous kēia, ua kāʻei ʻia ka waiwai string i kahi ʻōlelo hoʻohiki me ka hoʻohana ʻana i kahi mea hana.
Eia kahi hoʻolālā ʻokoʻa me ka ʻole o Async:
function fn() {
return Promise.resolve('hello');
}
fn().then(console.log);
// hello
I kēia hihia, hoʻihoʻi ʻia ka ʻōlelo hoʻohiki "manual". Hoʻopili mau ʻia kahi hana asynchronous i kahi ʻōlelo hoʻohiki hou.
Inā he primitive ka waiwai hoʻihoʻi, hoʻihoʻi ka hana async i ka waiwai ma ke kāʻei ʻana iā ia i kahi ʻōlelo hoʻohiki. Inā he mea hoʻohiki ka waiwai hoʻihoʻi, hoʻihoʻi ʻia kāna ʻōlelo hoʻoholo i kahi ʻōlelo hoʻohiki hou.
const p = Promise.resolve('hello')
p instanceof Promise;
// true
Promise.resolve(p) === p;
// true
Akā he aha ka mea inā he hewa i loko o kahi hana asynchronous?
async function foo() {
throw Error('bar');
}
foo().catch(console.log);
Inā ʻaʻole i hana ʻia, e hoʻihoʻi ka foo() i kahi ʻōlelo hoʻohiki me ka hōʻole. Ma kēia kūlana, e hoʻihoʻi ʻia ʻo Promise.reject me kahi hewa ma kahi o Promise.resolve.
Hoʻopuka mau nā hana Async i kahi ʻōlelo hoʻohiki, me ka nānā ʻole i ka mea i hoʻihoʻi ʻia.
Hoʻomaha nā hana Asynchronous i kēlā me kēia kali.
Hoʻopilikia ʻia nā ʻōlelo aʻoaʻo. No laila, inā he ʻōlelo hoʻohiki ka ʻōlelo, ua hoʻokuʻu ʻia ka hana async a hoʻokō ʻia ka ʻōlelo hoʻohiki. Inā ʻaʻole ia he ʻōlelo hoʻohiki, hoʻololi ʻia ia i ʻōlelo hoʻohiki ma o Promise.resolve a laila hoʻopau.
// 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);
A eia ka wehewehe ʻana o ka hana o ka fn.
Ma hope o ke kāhea ʻana, ua hoʻololi ʻia ka laina mua mai const a = kali 9; in const a = kali Promise.resolve(9);.
Ma hope o ka hoʻohana ʻana iā Await, ua hoʻokuʻu ʻia ka hana a hiki i ka loaʻa ʻana o kāna waiwai (ma ke kūlana o kēia manawa ʻo 9).
Hoʻomaha ʻo delayAndGetRandom(1000) i ka hoʻokō ʻana i ka hana fn a hoʻopau iā ia iho (ma hope o 1 kekona). Hoʻopau pono kēia i ka hana fn no 1 kekona.
ʻO ka delayAndGetRandom(1000) ma o ka hoʻoholo e hoʻihoʻi i kahi waiwai kūʻokoʻa, a laila hāʻawi ʻia i ka hoʻololi b.
ʻAe, ua like ka hihia me ka variable c me ka hihia me ka variable a. Ma hope o kēlā, pau nā mea a pau no ke kekona, akā i kēia manawa ʻaʻole e hoʻihoʻi ʻo delayAndGetRandom(1000) no ka mea ʻaʻole koi ʻia.
ʻO ka hopena, helu ʻia nā waiwai me ka hoʻohana ʻana i ke ʻano a + b * c. Hoʻopili ʻia ka hopena i kahi ʻōlelo hoʻohiki me ka hoʻohana ʻana iā Promise.resolve a hoʻihoʻi ʻia e ka hana.
Hoʻomanaʻo paha kēia mau hoʻomaha i nā mea hana ma ES6, akā aia kekahi mea kou mau kumu.
Hoʻoholo i ka pilikia
ʻĀ, ʻānō e nānā kākou i ka hopena o ka pilikia i ʻōlelo ʻia ma luna.
Hoʻohana ka hana hopeMyTask iā Await e kali i nā hopena o nā hana e like me queryDatabase, sendEmail, logTaskInFile, a me nā mea ʻē aʻe. Inā hoʻohālikelike ʻoe i kēia hoʻonā me ka mea i hoʻohana ʻia ai nā ʻōlelo hoʻohiki, e ʻike ʻia nā mea like. Eia naʻe, maʻalahi loa ka mana Async/Await i nā paʻakikī syntactic āpau. I kēia hihia, ʻaʻohe helu nui o nā kelepona a me nā kaulahao e like me .then/.catch.
Eia kahi hoʻonā me ka puka ʻana o nā helu, ʻelua mau koho.
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);
});
});
};
A eia kahi hoʻonā e hoʻohana ana i nā hana async.
async function printNumbersUsingAsync() {
for (let i = 0; i < 10; i++) {
await wait(i, Math.random() * 1000);
console.log(i);
}
}
Ke kuhi hewa
Hoʻopili ʻia nā kuhi hewa ʻole i ka ʻōlelo hoʻohiki i hōʻole ʻia. Eia nō naʻe, hiki i nā hana async ke hoʻohana i ka hoʻāʻo / hopu e hoʻoponopono i nā hewa i ka manawa like.
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 hana asynchronous e kūleʻa ana ("helu kūpono") a i ʻole me ka hewa ("E kala mai, nui loa ka helu").
Ma muli o ka manaʻo o ka laʻana ma luna nei e hiki ke hoʻokō i ka hikiRejectOrReturn, ʻo kona hemahema ka hopena i ka hoʻokō ʻana i ka poloka hopu. ʻO ka hopena, e pau ka hana foo me ka ʻike ʻole ʻia (inā ʻaʻohe mea i hoʻihoʻi ʻia ma ka poloka hoʻāʻo) a i ʻole me kahi hewa i loaʻa. ʻO ka hopena, ʻaʻole e hāʻule kēia hana no ka mea e mālama ka hoʻāʻo/hopu i ka hana foo ponoʻī.
Pono e hoʻolohe i ka ʻoiaʻiʻo i ka laʻana, hiki ke hoʻihoʻi ʻia mai ka foo. Hoʻopau ʻo Foo i kēia hihia me kahi helu kūpono a hoʻihoʻi paha i kahi Hapa ("E kala mai, nui loa ka helu"). ʻAʻole e hoʻokō ʻia ka poloka hopu.
ʻO ka pilikia ke hoʻihoʻi ʻo foo i ka ʻōlelo hoʻohiki i hāʻawi ʻia mai canRejectOrReturn. No laila, lilo ka hoʻonā i foo i mea hoʻonā e hiki keRejectOrReturn. I kēia hihia, ʻelua laina wale nō ke code:
Ma ke code ma luna, e puka maikaʻi ka foo me ka helu kūpono a me ka hewa i loaʻa. ʻAʻole e hōʻole ʻia ma ʻaneʻi. Akā e hoʻi ka foo me canRejectOrReturn, ʻaʻole me ka wehewehe ʻole. E hōʻoia i kēia ma ka wehe ʻana i ka laina hoʻihoʻi e kali canRejectOrReturn():
E like me kāu e ʻike ai, ʻaʻohe kali a hoʻi ʻole i ke code. No laila, puka mau ka foo me undefined me ka lohi 1 kekona. Akā e hoʻokō ʻia ka ʻōlelo hoʻohiki. Inā he hewa a hōʻole paha, e kāhea ʻia ʻo UnhandledPromiseRejectionWarning.
Nā hana Async i nā Callbacks
Hoʻohana pinepine ʻia nā hana Async ma .map a i ʻole .filter e like me nā callbacks. ʻO kahi laʻana ka hana fetchPublicReposCount(inoa inoa), e hoʻihoʻi i ka helu o nā waihona wehe ma GitHub. E ʻōlelo mākou aia ʻekolu mea hoʻohana nona nā metric a mākou e pono ai. Eia ke code no kēia hana:
Pono e hoʻolohe iā Await ma ka .map callback. Eia ka helu ʻana i nā ʻōlelo hoʻohiki, a ʻo .map he kelepona inoa ʻole no kēlā me kēia mea hoʻohana i kuhikuhi ʻia.
Hoʻohana mau ʻia o ka kali
E lawe kākou i kēia code ma ke ʻano he laʻana:
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;
}
Aia ka helu repo ma ka helu helu, a laila hoʻohui ʻia kēia helu i ka helu helu. ʻO ka pilikia me ke code a hiki i ka hōʻea ʻana o ka ʻikepili o ka mea hoʻohana mua mai ka kikowaena, e noho nā mea hoʻohana a pau ma ke ʻano standby. No laila, hoʻokahi wale nō mea hoʻohana e hana ʻia i ka manawa.
Inā, no ka laʻana, he 300 ms ke kaʻina hana hoʻokahi mea hoʻohana, a laila no nā mea hoʻohana a pau he kekona ia; ʻo ka manawa i hoʻohana ʻia ma ka laina laina e pili ana i ka helu o nā mea hoʻohana. Akā no ka loaʻa ʻana o ka helu repo ʻaʻole hilinaʻi i kekahi i kekahi, hiki ke hoʻohālikelike ʻia nā kaʻina hana. Pono kēia e hana me .map a me Promise.all:
Loaʻa iā Promise.all nā ʻōlelo hoʻohiki ma ke ʻano he hoʻokomo a hoʻihoʻi i kahi ʻōlelo hoʻohiki. ʻO ka hope, ma hope o ka pau ʻana o nā ʻōlelo hoʻohiki a pau a i ʻole ka hōʻole mua ʻana, ua pau. Malia paha ʻaʻole hoʻomaka lākou a pau i ka manawa like - i mea e hōʻoia ai i ka hoʻomaka like ʻana, hiki iā ʻoe ke hoʻohana i ka p-map.
hopena
Ke ulu nui nei nā hana Async no ka hoʻomohala ʻana. ʻAe, no ka hoʻohana ʻana i nā hana async, pono ʻoe e hoʻohana ʻO Async Iterators. Pono ka mea hoʻomohala JavaScript e ʻike i kēia.