Async: eachSeries avec un appel asynchrone imbriqué entraîne un dépassement de la taille maximale de la pile d'appels

Créé le 10 août 2016  ·  3Commentaires  ·  Source: caolan/async

Quelle version async utilisez-vous?

2.0.1

Dans quel environnement le problème s'est-il produit (version du nœud / version du navigateur)

Nœud 6.2.1
NPM 3.9.3

Qu'est-ce que tu as fait?

let counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        pCb();
      },
    ], cb);
  },
  () => console.log('done')
);

Que vous attendiez-vous?

Je m'attendais à ce que chacune des itérations se produise, ce qui aboutirait à ce que les deux derniers console.log soient «1» et «done».

Quel a été le résultat réel?

Après moins de 1000 itérations, je recevrais cette erreur:

RangeError: taille maximale de la pile d'appels dépassée

Lorsque je suis revenu à async 1.5.2, le code ci-dessus a fonctionné comme prévu.

question

Commentaire le plus utile

La raison pour laquelle cela a fonctionné dans async 1.5.2 est que nous nous sommes assurés que le rappel était toujours appelé de manière asynchrone dans cette version. Dans la version 2, nous avons supprimé cette garde (voir https://github.com/caolan/async/blob/master/intro.md#synchronous-iteration-functions)

Donc, dans votre cas, pour corriger le script, vous pouvez soit utiliser async.ensureAsync(cb) ou async.setImmediate(cb) pour contourner le problème de récursivité:

var counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        async.setImmediate(pCb);
      },
    ], cb);
  },
  () => console.log('done')
);

Tous les 3 commentaires

+1

+1

La raison pour laquelle cela a fonctionné dans async 1.5.2 est que nous nous sommes assurés que le rappel était toujours appelé de manière asynchrone dans cette version. Dans la version 2, nous avons supprimé cette garde (voir https://github.com/caolan/async/blob/master/intro.md#synchronous-iteration-functions)

Donc, dans votre cas, pour corriger le script, vous pouvez soit utiliser async.ensureAsync(cb) ou async.setImmediate(cb) pour contourner le problème de récursivité:

var counter = 2000;

async.eachSeries(
  new Array(counter),
  (item, cb) => {
    async.parallel([
      (pCb) => {
        console.log(counter--);
        async.setImmediate(pCb);
      },
    ], cb);
  },
  () => console.log('done')
);
Cette page vous a été utile?
0 / 5 - 0 notes