J'essaie d'interroger, cela obtiendrait la totalité de la quantité de gain et de retrait et de la somme, mais d'une manière ou d'une autre, une fois que la boucle de Foreach est terminée et se ferme, toutes les valeurs actualisées que j'ai placées dans une variable retour à leurs valeurs d'origine. < Pré> xxx pré> p>
5 Réponses :
foreach code> est asynchrone. Donc, la console.log fonctionne avant votre boucle de mutation. Vous pouvez le rendre synchrone en utilisant mapper code>, mais même à ce moment-là, vous avez des appels asynchrones à l'intérieur. Vous devrez l'aplatiser davantage - probablement en faisant la promesse.Tous sur une carte, puis réduisez la sortie de cela. P>
foreach code> et cartographique code> sont synchrones, mais vous avez raison d'utiliser carte code> avec promess.All code>
Merci, je viens de vérifier - et je vis dans l'illusion erronée que pourach est asynchrone!
Je pense que la raison pourrait être celle des désappelées.findone () et des gains.findone () sont toutes deux des fonctions asynchrones. Cela signifie qu'ils ne reviennent pas immédiatement avec une valeur, d'où vos variables sont toujours la même après la boucle. P>
Vous exécutez un code asynchrone à l'intérieur du foreach code> et foreach code> n'attend pas que le code asynchrone finira, pour le faire, vous devez envelopper votre code ASYNC avec une primitive d'attente , comme ceci
Voici une approche fonctionnelle qui supprime l'effet secondaire de mutation à l'intérieur de la boucle. Vous avez besoin d'un moteur prenant en charge la propagation du repos de l'objet pour cela:
async function calculate(userplans) {
const add = (acc, n) => acc + n;
const flatten = (acc, e) => ({
depositEarnings: [...acc.depositEarnings, e.depositEarnings],
earnings: [...acc.earnings, e.earnings]
});
const {depositEarnings, earnings} = (await Promise.all(userplans
.map(async (up) => ({
depositEarnings: await DepositEarning.findOne({deposit: up.deposit._id}),
earnings: await Earning.findOne({deposit: up.deposit._id})
}))))
.reduce(flatten, {depositEarnings: [], earnings: []});
const withdrawalBalance = depositEarnings
.map(d => parseInt(d.WithdrawableBalance, 10))
.reduce(add, 0);
const totalEarning = earnings
.map(e => parseInt(e.Earning, 10))
.reduce(add, 0);
console.log(withdrawalBalance);
console.log(totalEarning);
}
juste pour ajouter mes deux cents, p>
Au fur et à mesure que d'autres réponses ont déclaré, votre L'appel est enfoncé pour appeler la pile, puis il est supprimé em> de la pile d'appel. Parce que le travail sera traité par l'API maintenant. l'appel à p>
est ajouté à la pile d'appels et quelle est la valeur en ce moment? 0 0. P>
L'API, lorsqu'il est fait avec le travail, ajoutera la fonction dans la file d'attente de tâches code> et à partir de celui-ci, Et c'est alors couru. Et ensuite vous aurez les vraies valeurs de foreach code> utilise un code asynchrone. Il utilise une API qui ne fait pas partie de JS. P>
console.log (retraitbalance);
console.log (totalelarning); code> p>
boucle d'événement code> vérifiera si la pile d'appel est vide. . Comme il est vide en ce moment, ajoutera la fonction dans la pile d'appels. p>
retrait et
Nombre total d'appréciations code> valeurs. P>
"retourne à sa valeur d'origine" - Nope. Il n'était tout simplement pas encore mis à jour.