asynkron - Vad är skillnaden mellan JavaScript-löften och async await?
Jag har redan använt funktioner från ECMAScript 6 och ECMAScript 7 (tack vare Babel) i mina applikationer - både mobila och webb.
Det första steget var uppenbarligen till ECMAScript 6-nivåer. Jag lärde mig många asynkrona mönster, löften (vilka verkligen är lovande), generatorer (inte säker på varför *-symbolen), etc. Av dessa passade löften mitt syfte ganska bra. Och jag har använt dem mycket i mina applikationer.
Här är ett exempel/pseudokod på hur jag har implementerat ett grundläggande löfte-
var myPromise = new Promise(
function (resolve,reject) {
var x = MyDataStore(myObj);
resolve(x);
});
myPromise.then(
function (x) {
init(x);
});
När tiden gick stötte jag på ECMAScript 7-funktioner, och en av dem var ASYNC och AWAIT-nyckelord/funktioner. Dessa tillsammans gör stor skillnad. Jag har börjat ersätta några av mina promises med async & await. De verkar tillföra stort värde till programmeringsstilen.
Här är återigen en pseudokod över hur min async, await-funktion ser ut.
async function myAsyncFunction (myObj) {
var x = new MyDataStore(myObj);
return await x.init();
}
var returnVal = await myAsyncFunction(obj);
Om man bortser från syntaxfelen (om några), gör båda exakt samma sak, det är vad jag känner. Jag har nästan kunnat ersätta de flesta av mina promises med async, await.
Varför behövs async, await när löften gör ett liknande jobb?
Löser async, await ett större problem? Eller var det bara en annan lösning på callback-helvetet?
Som jag sa tidigare kan jag använda promises och async, await för att lösa samma problem. Finns det något specifikt som async await löste?
Ytterligare anteckningar:
Jag har använt async, await och promises flitigt i mina React-projekt och Node.js-moduler. Speciellt React har varit tidigt ute och antagit många ECMAScript 6- och ECMAScript 7-funktioner.
Svar #1
Varför behövs async, await när Promises gör liknande jobb? Löser async, await ett större problem?
async/await ger dig helt enkelt en synkron känsla till asynkron kod. Det är en mycket elegant form av syntaktiskt socker.
För enkla frågor och datamanipulation kan Promises vara enkla, men om du stöter på situationer där det finns komplex datamanipulation och liknande, är det lättare att förstå vad som pågår om koden helt enkelt ser ut som om den är synkron (med andra ord är syntax i sig en form av "oavsiktlig komplexitet" som async/await kan kringgå).
Om du är intresserad av att veta kan du använda ett bibliotek som co (tillsammans med generatorer) för att ge samma typ av känsla. Sådana saker har utvecklats för att lösa problemet som async/await i slutändan löser (inbyggt).
Svar #2
Async/Await ger en mycket trevligare syntax i mer komplexa scenarier. Särskilt allt som har att göra med loopar eller vissa andra konstruktioner som try/catch.
Till exempel:
while (!value) {
const intermediate = await operation1();
value = await operation2(intermediate);
}
Detta exempel skulle vara avsevärt mer komplicerat enbart med Promises.
Svar #3
Varför behövs async, await när Promises gör ett liknande jobb? Löser async, await ett större problem? Eller var det bara en annan lösning på callback-helvetet? Som jag sa tidigare, kan jag använda Promises och Async, Await för att lösa samma problem. Finns det något specifikt som Async Await löste?
Det första du måste förstå är att async/await-syntaxen bara är syntaktiskt socker som är avsedd att förbättra löften. Faktum är att returvärdet av en async-funktion är ett löfte. async/await-syntaxen ger oss möjligheten att skriva asynkront på ett synkront sätt. Här är ett exempel:
Löfteskedjning:
function logFetch(url) {
return fetch(url)
.then(response => response.text())
.then(text => {
console.log(text);
}).catch(err => {
console.error('fetch failed', err);
});
}
Asynkron funktion:
async function logFetch(url) {
try {
const response = await fetch(url);
console.log(await response.text());
}
catch (err) {
console.log('fetch failed', err);
}
}
I exemplet ovan väntar await på att löftet (fetch(url)) antingen ska lösas eller avvisas. Om löftet löses lagras värdet i variabeln response, och om löftet avvisas skulle det kasta ett fel och därmed gå in i catch-blocket.
Vi kan redan se att användning av async/await kan vara mer läsbar än att kedja promises. Detta är särskilt sant när antalet promises vi använder ökar. Både Promise-kedjning och async/await löser problemet med callback-helvete och vilken metod du väljer är en fråga om personlig preferens.
Svar #4
Async/await kan hjälpa till att göra din kod renare och mer läsbar i fall där du behöver komplicerat kontrollflöde. Det ger också mer felsökningsvänlig kod. Och gör det möjligt att hantera både synkrona och asynkrona fel med bara try/catch.
Jag skrev nyligen detta inlägg som visar fördelarna med async/await jämfört med promises i några vanliga användningsfall med kodexempel: 6 anledningar till varför JavaScript Async/Await slår promises med hästlängder (handledning)
