Async: Mendapatkan kesalahan baru menggunakan Async dengan Node 6.2.2 "Panggilan balik sudah dipanggil"

Dibuat pada 27 Jun 2016  ·  12Komentar  ·  Sumber: caolan/async

Versi async apa yang Anda gunakan?

3.9.5

Di lingkungan mana masalah terjadi (Versi node/versi browser)

Simpul 6.2.2 dan 5.0.71.52

Apa yang kamu lakukan?

Aplikasi ini

var fs = require('fs'),
    async = require('async'),
    _dir = './data/';

var writeStream = fs.createWriteStream('./log.txt',
      {'flags' : 'a',
       'encoding' : 'utf8',
       'mode' : 0666});

async.waterfall([
   function readDir(callback) {
      fs.readdir(_dir, function(err, files) {
         callback(err,files);
      });
   },
   function loopFiles(files, callback) {
      files.forEach(function (name) {
         callback (null, name);
      });
   },

   function checkFile(file, callback) {
      fs.stat(_dir + file, function(err, stats) {
         callback(err, stats, file);
      });
   },
   function readData(stats, file, callback) {
      if (stats.isFile())
         fs.readFile(_dir + file, 'utf8', function(err, data){
           callback(err,file,data);
       });
   },
   function modify(file, text, callback) {
      var adjdata=text.replace(/somecompany\.com/g,'burningbird.net');
      callback(null, file, adjdata);
   },
   function writeData(file, text, callback) {
       fs.writeFile(_dir + file, text, function(err) {
          callback(err,file);
       });
   },

   function logChange(file, callback) {
       writeStream.write('changed ' + file + '\n', 'utf8',
                       function(err) {
          callback(err);
      });
   }
], function (err) {
         if (err) {
            console.log(err.message);
         } else {
            console.log('modified files');
         }
});

Apa yang Anda harapkan terjadi?

Bahwa saya tidak akan mendapatkan kesalahan

Apa hasil sebenarnya?

aku mengerti

/home/examples/public_html/learnnode2-examples/chap3/node_modules/async/dist/async.js:837
if (fn === null) throw new Error("Callback sudah dipanggil.");
^

Kesalahan: Panggilan balik sudah dipanggil.

Fungsi panggilan balik di bagian kode berikut

function loopFiles(file, panggilan balik) {
files.forEach(fungsi (nama) {
panggilan balik (null, nama);
});
},

Hilang pada putaran kedua.

Saya telah berhasil menjalankan kode ini melalui beberapa versi Node.js. Saya yakin saya menguji ini ketika Node 6 pertama kali dirilis.

Pada iterasi kedua, fungsinya tidak nol, tetapi ada sesuatu yang terjadi dalam kode Async yang mengakibatkan kesalahan ini.

question

Semua 12 komentar

Karena Anda menelepon balik berkali-kali di sini:

function loopFiles(files, callback) {
    files.forEach(function(name) {
        callback(null, name);
    });
},

Silakan gunakan async.forEach untuk kasus ini.

Menarik. Saya tidak punya masalah dengan versi Node sebelumnya, dan faktanya, ini berhasil dijalankan di Node 6.0.0 di mesin Windows saya.

Jadi, ada sesuatu yang berubah antara 6.0.0 dan 6.2.2 yang menyebabkan Async terputus dengan penggunaan forEach bawaan.

Sekedar informasi, async.forEach tidak berfungsi. Itu tidak crash, tetapi tidak bekerja.

   function loopFiles(files, callback) {
      async.forEach(files, function (name, callback) {
         callback (null, name);
      });
   },

Dan sejujurnya, saya tidak yakin itu forEach yang menyebabkan masalah. Jika saya salah menggunakannya, beri tahu saya.

Oke, saya menyerah.

Saya memperbarui mesin Windows saya ke 6.2.2, dan kode ini berfungsi. Tapi itu tidak bekerja di mesin Linux saya. Keduanya dibangun di atas mesin V8 yang sama. Keduanya menggunakan versi Async yang sama. Keduanya memiliki direktori file contoh yang sama.

Di Linux, kesalahan dilemparkan. Di Windows, tidak.

@shelleyp air terjun Anda tidak terstruktur dengan benar untuk banyak file. Saya pikir Anda ingin memisahkannya menjadi dua air terjun atau meminta setiap langkah mengharapkan sebuah array.

Alasan perubahan async.forEach tidak berhasil adalah karena Anda tidak memanggil callback loopFiles . Fungsi itu tidak melakukan apa yang Anda inginkan, jika Anda hanya ingin memproses file pertama, ubah loopFiles menjadi (files, callback) => callback(null, files[0]) jika tidak, Anda harus memiliki checkFiles , readData dan modify mengharapkan array (atau buat air terjun kedua)

Saya tidak akan memperbaiki semua kode Anda, tetapi ini adalah cara saya mengubah fungsi checkFiles

async.waterfall([
   function readDir(callback) {
      fs.readdir(_dir, callback);
   },

   function checkFile(files, callback) {
      async.map(files, (file, cb) => {
         fs.stat(_dir + file, function(err, stats) {
            cb(err, {stat: stats, file: file});
         });
      }, (err, stats) => {
         callback(err, stats);
      });
   },

....

Tidak apa-apa.

Ketahuilah bahwa ini berfungsi hingga 6.2.2, jadi apa pun yang menyebabkan kode saya tidak berfungsi dapat menyebabkan kode orang lain tidak berfungsi.

Aneh satu-satunya hal yang harus membuat kode itu berfungsi adalah jika daftar readdir
satu file (juga rusak untuk 0 file).

Apakah Anda keberatan memeriksa ulang output readdir di kedua versi anggukan?
Pada 27 Jun 2016 17:55, "Shelley Powers" [email protected] menulis:

Tidak apa-apa.

Ketahuilah bahwa ini berfungsi hingga 6.2.2, jadi apa pun yang menyebabkan kode saya tidak
pekerjaan dapat menyebabkan kode orang lain tidak berfungsi.


Anda menerima ini karena Anda mengubah status buka/tutup.
Balas email ini secara langsung, lihat di GitHub
https://github.com/caolan/async/issues/1199#issuecomment -228887866, atau bisukan
benang
https://github.com/notifications/unsubscribe/ADUIEAfvkwCmdjmkIZIjipFGYgPQ6SzYks5qQEbpgaJpZM4I_Nsg
.

Kode ini selalu bekerja dengan banyak file. Nah, sampai 6.2.2 di Linux.

Tapi hanya memeriksa pada Windows. Yup, bekerja dengan empat file.

Output dari readdir adalah [ 'data1.txt', 'data2.txt', 'data3.txt', 'data4.txt' ]

input ke loopFiles adalah sama.

Pada saat itu, dengan forEach, setiap panggilan balik mendapatkan nama file individual.

Jika saya pernah mengalami dinding bata dengan array, saya tidak akan menggunakan pendekatan ini. Tapi itu selalu berhasil.

Tidak masalah, saya selalu dapat memperbarui kode untuk menghapus penanganan array. Masalah sebenarnya adalah ia bekerja di satu lingkungan tetapi tidak di lingkungan lain. Namun Node, V8, dan Async adalah versi yang sama.

Saya baru saja menjalankan kode yang sedikit dimodifikasi di Ubuntu 16.04 di node 6.0.0 dan 6.2.2. Dalam kedua kasus saya mendapatkan hasil yang sama:

  • data1.txt, callback untuk item pertama (data1.txt)
  • Kesalahan: panggilan balik sudah dipanggil

Skrip yang dimodifikasi:

var fs = require('fs'),
    async = require('async'),
    _dir = './data/';

async.waterfall([
   function readDir(callback) {
      fs.readdir(_dir, callback);
   },
   function loopFiles(files, callback) {
      files.forEach(function (name) {
         callback (null, name);
      });
   },
   console.log.bind(console)
], console.error)
$ ls data
> data1.txt  data2.txt

Tapi Anda tidak mencobanya di Windows.

Tentu, saya menutupnya karena bukan masalah asinkron.

Pada Senin, 27 Jun 2016 jam 20:20, Shelley Powers [email protected]
menulis:

Tapi Anda tidak mencobanya di Windows.


Anda menerima ini karena Anda mengubah status buka/tutup.
Balas email ini secara langsung, lihat di GitHub
https://github.com/caolan/async/issues/1199#issuecomment -228914233, atau bisukan
benang
https://github.com/notifications/unsubscribe/ADUIEDNwRmcEjcAnVmSCHBBIHvdM6DL3ks5qQGiwgaJpZM4I_Nsg
.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat