Async: 'Ukuran tumpukan panggilan maksimum terlampaui' menggunakan async.forEachLimit

Dibuat pada 26 Des 2011  ·  15Komentar  ·  Sumber: caolan/async

async = require('async');

var documents = ['a', 'b', 'c', 'd', 'e', 'f'];

async.forEachLimit(documents, 2, function(item, callback) {
  console.log(".", item);
  callback(null);
}, function(err){
  console.log("end", err);
});

Catatan

$ node test.js
. a
. a
. a
. a
. a
. a
end undefined
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
[...]

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
RangeError: Maximum call stack size exceeded

Komentar yang paling membantu

Saya sedang melakukan operasi sinkronisasi. Saya memperbaikinya dengan mengubah dari:

callback();

ke

setTimeout(callback, 0);

Semua 15 komentar

forEachLimit terlihat salah.

started += 1 running += 1

harus dipindahkan di depan panggilan iterator. arr[started] juga harus diubah menjadi arr[started - 1]

Catatan: Anda hanya akan menemukan bug ini jika kode di dalam iterator iterator memanggil panggilan balik di centang yang sama.

BERHENTI memanggil fungsi SYNC di async.js

Saya mengalami masalah ini ketika saya memiliki return callback(null); bersyarat di iterator saya. Itu berarti saya harus melakukan hal yang lebih cerdas, yaitu memfilter array menggunakan Array.filter sebelum menerapkan async.forEach , jadi itu sebenarnya membantu...

Jika Anda _benar-benar_ berpikir Anda harus melakukannya, Anda dapat mengatasinya dengan menggunakan process.nextTick(function() { callback(); }) .

@jacobrask Itu bekerja dengan baik. Terima kasih

Melakukan callback(null); adalah sinkron. Anda perlu memanggilnya secara tidak sinkron, ala process.nextTick(callback) , atau process.nextTick(function() { callback(null); }); . Seperti kata @bobrik , berhenti memanggil fungsi sinkronisasi di async :)

Mengatakan "berhenti memanggil fungsi sinkronisasi di async" tidak ada gunanya - itu rusak, dan hanya di forEachLimit ini tampaknya menjadi masalah.

async.forEachLimit(['a','b'], 1, function(item, callback){
  if(something) {
    doStuff(function(){ callback(); });
  } else {
    callback();
  }
});

Meskipun saya dapat dengan mudah melindungi dari contoh yang sangat spesifik itu (seperti yang disebutkan @jacobrask dengan memfilter), bagaimana jika doStuff() (yang mungkin berada di perpustakaan di luar kendali saya) memutuskan untuk memanggil panggilan balik saya tanpa process.nextTick()?

Saya telah menambahkan beberapa kode untuk memanggil async.nextTick jika mendeteksi iterator sinkron yang harus menghindari stack overflow dalam kasus ini. Tapi serius, BERHENTI MEMANGGIL FUNGSI SYNC DI ASYNC! ...jadikan fungsi Anda secara konsisten sinkron atau asinkron secara konsisten ;)

Ini juga terjadi pada saya dengan async.eachSeries .

Juga terjadi di mapLimit , dan ya fungsi saya disinkronkan karena ini adalah fungsi tiruan. Lalu saya membungkusnya dalam setImmediate , masalahnya terpecahkan.

Terjadi dengan saya di async.forEachOfLimit

Menghadapi masalah yang sama dengan async.waterfall .

async.queue juga, tentu saja.

Saya sedang melakukan operasi sinkronisasi. Saya memperbaikinya dengan mengubah dari:

callback();

ke

setTimeout(callback, 0);

Ini terjadi pada saya ketika saya memiliki tangkapan yang melekat pada sebuah janji. Sesuatu seperti:
async.forEach(items, (item:any, callback:Function) => { someAsyncPromise(item).then(() => { callback(); }).catch((err) => { //console error or something here callback(); }) });

catch harus dilempar sebelum bit async dalam janji, karena kesalahan ini hanya terjadi ketika pengecualian terjadi di janji.

`

Saya mengerti bahwa kita harus berhenti memanggil fungsi sinkronisasi di async.

Tetapi, jika memanggil fungsi sinkronisasi callback() di dalam badan async salah, mengapa dokumentasi async menunjukkannya dalam contoh?

Dapatkah seseorang membantu saya memahami apa cara yang 'tepat' untuk bekerja dengan modul async?

Berikut ini contoh langsung dari dokumentasi async:

// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {

    // Perform operation on file here.
    console.log('Processing file ' + file);

    if( file.length > 32 ) {
      console.log('This file name is too long');
      callback('File name too long');
    } else {
      // Do work to process file here
      console.log('File processed');
      callback();
    }
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if( err ) {
      // One of the iterations produced an error.
      // All processing will now stop.
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

https://caolan.github.io/async/docs.html#each

Terima kasih!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat