Cet article vous parle principalement de meilleures solutions pour l'asynchronisme de l'expérience JavaScript. Les amis qui ont besoin de cet aspect peuvent le suivre pour référence. J'espère qu'il pourra aider tout le monde.
1. L'histoire évolutive des solutions asynchrones
Le fonctionnement asynchrone de JavaScript a toujours été un problème gênant, c'est pourquoi les gens continuent de proposer diverses solutions. Cela remonte à la première fonction de rappel (un vieil ami d'ajax), à Promise (pas un nouvel ami), puis au générateur ES6 (un ami puissant).
Il y a quelques années, nous avons peut-être utilisé un Async.js relativement célèbre, mais il ne s'est pas débarrassé de la fonction de rappel, et la gestion des erreurs a également suivi la convention du "le premier paramètre de la fonction de rappel est utilisé pour passer le erreur". L'enfer des rappels bien connu était toujours un problème important jusqu'à ce que Generator change ce style asynchrone.
Mais avec l'émergence de l'attente asynchrone d'ES7 (le nouvel ami de Bunker), nous pouvons facilement écrire du code de style synchrone tout en disposant d'un mécanisme asynchrone. Cela peut être considéré comme la solution la plus simple, la plus élégante et la meilleure à l'heure actuelle.
2. syntaxe d'attente asynchrone
La syntaxe d'attente asynchrone est relativement simple et peut être considérée comme du sucre syntaxique pour Generator. Elle est plus sémantique que l'astérisque et le rendement. Ce qui suit est un exemple simple qui affiche hello world après 1 seconde :
function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value) } asyncPrint('hello world', 1000);
await ne peut être utilisé que dans des fonctions asynchrones. S'il est utilisé dans des fonctions ordinaires, une erreur se produira. être signalé
await est suivi d'un objet Promise (bien sûr, d'autres valeurs sont également possibles, mais elle sera regroupée dans une Promise qui se résout immédiatement, ce qui n'a aucun sens)
await attendra Le résultat de la promesse est renvoyé puis l'exécution continue
Bien que wait attend l'objet Promise, il n'est pas nécessaire d'écrire .then() La valeur de retour. peut être obtenu directement. Après avoir affiné le code ci-dessus, il s'avère que le résultat de la valeur de retour est également possible. Sortie hello world :
function timeout(ms) { return new Promise((resolve) => { setTimeout(_ => {resolve('hello world')}, ms); }); } async function asyncPrint(ms) { let result = await timeout(ms); console.log(result) } asyncPrint(1000);
3. async. Gestion des erreurs wait
Comme mentionné précédemment, bien que wait attend un objet Promise, il n'est pas nécessaire qu'il soit Write .then(), vous n'avez donc pas réellement besoin d'écrire .catch() . Vous pouvez détecter les erreurs directement avec try catch. Cela peut éviter un code de gestion des erreurs redondant et fastidieux :
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(_ => {reject('error')}, ms);//reject模拟出错,返回error }); } async function asyncPrint(ms) { try { console.log('start'); await timeout(ms);//这里返回了错误 console.log('end');//所以这句代码不会被执行了 } catch(err) { console.log(err); //这里捕捉到错误error } } asyncPrint(1000);
S'il y en a plusieurs. attend, ils peuvent être placés ensemble dans try catch :
async function main() { try { const async1 = await firstAsync(); const async2 = await secondAsync(); const async3 = await thirdAsync(); } catch (err) { console.error(err); } }
4. Remarque sur l'attente asynchrone Cliquez sur
1). auparavant, l'objet Promise derrière la commande wait est susceptible d'être rejeté ou de constituer une erreur logique, il est donc préférable de mettre wait dans le bloc de code try catch.
2). Pour les opérations asynchrones de plusieurs commandes wait, s'il n'y a pas de dépendance, laissez-les se déclencher en même temps.
const async1 = await firstAsync(); const async2 = await secondAsync();
Dans le code ci-dessus, si async1 et async2 sont deux opérations asynchrones indépendantes, écrire de cette façon prendra plus de temps, car il ne sera exécuté qu'après firstAsync est terminé. secondAsync peut être géré avec élégance avec Promise.all :
let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);
3). will Erreur signalée :
async function main() { let docs = [{}, {}, {}]; //报错 await is only valid in async function docs.forEach(function (doc) { await post(doc); console.log('main'); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
Ajoutez simplement async à la méthode interne forEach :
async function main() { let docs = [{}, {}, {}]; docs.forEach(async function (doc) { await post(doc); console.log('main'); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
Mais Vous constaterez que les trois secteurs sont émis en même temps, ce qui signifie que le message est exécuté simultanément et non séquentiellement. Passer à for peut résoudre le problème. Les trois secteurs sont émis à 1 seconde d'intervalle :
<. 🎜>
async function main() { let docs = [{}, {}, {}]; for (let doc of docs) { await post(doc); console.log('main'); } } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
Qu'est-ce que JavaScript asynchrone
Introduction à 4 méthodes de programmation asynchrone Javascript
Explication détaillée des exemples d'exécution asynchrone JavaScript et de contrôle de flux d'opérations
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!