Recommandations d'apprentissage associées : Tutoriel d'apprentissage javascript
Promesse Concernant l'API, tout le monde devrait pouvoir l'utiliser avec compétence, mais vous pouvez encore avoir des angles morts en matière de connaissances liés aux microtâches.
Avant de commencer le texte principal, donnons d'abord le ton à l'avance pour une partie du contenu impliqué dans cet article.
Dans Promise, seuls les rappels qui doivent être exécutés après que des changements d'état soient impliqués sont considérés comme des microtâches, telles que then
, catch
, finally
. Toutes les autres exécutions de code sont des macrotâches (implémentation synchrone).
Dans l'image ci-dessus, le bleu représente une exécution synchrone et le jaune représente une exécution asynchrone (jetée dans la file d'attente des microtâches).
Examinons ce problème selon la spécification ecma :
Si le statut de la promesse est en attente à ce moment-là, alors les rappels réussis ou échoués seront ajoutés à [[PromiseFulfillReactions]]
et [[PromiseRejectReactions]]
Moyen. Si vous avez examiné le code manuscrit de Promise, vous devriez pouvoir constater qu'il existe deux tableaux stockant ces fonctions de rappel.
Si le statut de la promesse n'est pas en attente à ce moment-là, le rappel deviendra des tâches promises, qui sont des microtâches.
Après avoir compris les connaissances ci-dessus, le film principal commence.
Promise.resolve() .then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1"); }); }) .then(() => { console.log("then2"); });复制代码
Tout le monde devrait pouvoir obtenir la bonne réponse à partir du code ci-dessus : then1 → then1-1 → then2
.
Bien que then
soit exécuté de manière synchrone et que le statut ait changé. Mais cela ne signifie pas que chaque fois que nous rencontrons then
, nous devons lancer son rappel dans la file d'attente des microtâches, nous devons plutôt attendre la fin du rappel de then
, puis effectuer l'opération correspondante en fonction de la situation. .
Sur cette base, nous pouvons tirer la première conclusion : Dans l'appel en chaîne, seulement après l'exécution du rappel du then
précédent, ce qui suit < Seuls les rappels en 🎜>then
seront ajoutés à la file d'attente des microtâches.
, le rappel dans Promise resolve
entrera immédiatement dans la file d'attente des microtâches. then
let p = Promise.resolve(); p.then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1"); }); }).then(() => { console.log("then1-2"); }); p.then(() => { console.log("then2"); }); 复制代码
sera sorti après then2
, mais la situation réelle est le contraire. then1-1
Le début de chaque appel en chaîne entrera d'abord dans la file d'attente des microtâches dans l'ordre.
Ensuite, changeons la méthode d'écriture :let p = Promise.resolve().then(() => { console.log("then1"); Promise.resolve().then(() => { console.log("then1-1"); }); }).then(() => { console.log("then2"); }); p.then(() => { console.log("then3"); });复制代码
renverra une nouvelle promesse à chaque fois, et le then
à ce moment-là le temps n'est plusp
est généré par le dernier Promise.resolve()
, donc then
doit être imprimé après then3
. then2
Le début de chaque appel en chaîne de la même promesse entrera d'abord dans la file d'attente des microtâches dans l'ordre.
AvancéVous pouvez deviner quand sera imprimé ? then1-2
Promise.resolve() .then(() => { console.log("then1"); Promise.resolve() .then(() => { console.log("then1-1"); return 1; }) .then(() => { console.log("then1-2"); }); }) .then(() => { console.log("then2"); }) .then(() => { console.log("then3"); }) .then(() => { console.log("then4"); });复制代码
Suivant A resolve
le rappel entre dans la file d'attente des microtâches et est exécuté Après avoir imprimé then
then1
, le premier rappel interne resolve
entre dans la file d'attente des microtâches, à ce moment. , tous les premiers rappels then
externes ont été exécutés et le deuxième rappel then
externe doit être inséré dans la file d'attente des microtâches. then
et then1-1
, puis insérez les rappels dans les then2
suivants dans la file d'attente des microtâches then
et then1-2
, le contenu suivant ne sera pas expliqué un par unthen3
, le résultat sera grand Pas pareil : return 1
Promise.resolve() .then(() => { console.log("then1"); Promise.resolve() .then(() => { console.log("then1-1"); return Promise.resolve(); }) .then(() => { console.log("then1-2"); }); }) .then(() => { console.log("then2"); }) .then(() => { console.log("then3"); }) .then(() => { console.log("then4"); });复制代码
, devinez quand return Promise.resolve()
sera imprimé ? then1-2
La réponse est la dernière imprimée.
Pourquoi y a-t-il un si grand changement dans l'ordre d'exécution des microtâches alors qu'il y a choses différentes dans then
? Voici l'analyse de l'auteur. return
PS:then
返回一个新的 Promise,并且会用这个 Promise 去 resolve
返回值,这个概念需要大家先了解一下。
根据规范 2.3.2,如果 resolve
了一个 Promise,需要为其加上一个 then
并 resolve
。
if (x instanceof MyPromise) { if (x.currentState === PENDING) { } else { x.then(resolve, reject); } return; }复制代码
上述代码节选自手写 Promise 实现。
那么根据 A+ 规范来说,如果我们在 then
中返回了 Promise.resolve
的话会多入队一次微任务,但是这个结论还是与实际不符的,因此我们还需要寻找其他权威的文档。
根据规范 25.6.1.3.2,当 Promise resolve
了一个 Promise 时,会产生一个NewPromiseResolveThenableJob,这是属于 Promise Jobs 中的一种,也就是微任务。
This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.
并且该 Jobs 还会调用一次 then
函数来 resolve Promise
,这也就又生成了一次微任务。
这就是为什么会触发两次微任务的来源。
文章到这里就完结了,大家有什么疑问都可以在评论区提出。
想了解更多编程学习,敬请关注php培训栏目!
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!