Async: الحصول على خطأ جديد باستخدام Async مع Node 6.2.2 "تم استدعاء رد الاتصال بالفعل"

تم إنشاؤها على ٢٧ يونيو ٢٠١٦  ·  12تعليقات  ·  مصدر: caolan/async

ما هو إصدار غير متزامن الذي تستخدمه؟

3.9.5

ما البيئة التي حدثت فيها المشكلة في (إصدار العقدة / إصدار المتصفح)

العقدة 6.2.2 و 5.0.71.52

ماذا فعلت؟

هذا التطبيق

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');
         }
});

ماذا تتوقع أن يحدث؟

لن أحصل على خطأ

ماذا كانت النتيجة الفعلية؟

انا احصل

/home/examples/public_html/learnnode2-examples/chap3/node_modules/async/dist/async.js:837
إذا (fn === null) طرح خطأ جديد ("تم استدعاء رد الاتصال بالفعل.") ؛
^

خطأ: تم استدعاء رد الاتصال بالفعل.

وظيفة رد الاتصال في القسم التالي من الكود

وظيفة loopFiles (ملفات ، رد اتصال) {
files.forEach (الوظيفة (الاسم) {
رد الاتصال (فارغ ، الاسم) ؛
}) ؛
} ،

ضاع في الجولة الثانية.

لقد قمت بتشغيل هذا الرمز بنجاح من خلال عدة إصدارات من Node. أعتقد أنني اختبرت هذا عندما تم إصدار Node 6 لأول مرة.

في التكرار الثاني ، لا تكون الوظيفة فارغة ، ولكن يحدث شيء ما في رمز Async مما أدى إلى حدوث هذا الخطأ.

question

ال 12 كومينتر

لأنك اتصلت بمعاودة الاتصال عدة مرات هنا:

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

الرجاء استخدام async.forEach لهذه الحالة.

مثير للإعجاب. لم أواجه أي مشاكل مع الإصدارات السابقة من Node ، وفي الواقع ، قمت بتشغيل هذا بنجاح في Node 6.0.0 في جهاز Windows الخاص بي.

لذلك ، تغير شيء ما بين 6.0.0 و 6.2.2 مما يتسبب في توقف Async مع استخدام forEach المدمج.

مجرد لمعلوماتك ، غير متزامن للجميع لا يعمل. إنه لا ينهار ، لكنه لا يعمل.

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

وبصراحة ، لست متأكدًا من أنها السبب في كل مشكلة. إذا كنت أستخدمه بشكل غير صحيح ، فيرجى إبلاغي بذلك.

حسنا انا استسلم.

لقد قمت بتحديث جهاز Windows الخاص بي إلى 6.2.2 ، ويعمل هذا الرمز. لكنها لا تعمل على جهاز Linux الخاص بي. كلاهما مبنيان على نفس محرك V8. كلاهما يستخدم نفس الإصدار من Async. كلاهما لهما نفس أدلة الملفات.

في Linux ، حدث خطأ. في Windows ، لا.

shelleyp شلالك منظم بشكل غير صحيح لملفات متعددة. أعتقد أنك تريد فصله إلى شلالين أو أن تتوقع كل خطوة وجود مصفوفة.

سبب عدم نجاح تغيير async.forEach هو أنك لا تتصل باستدعاء loopFiles . هذه الوظيفة لا تفعل ما تريده على أي حال ، إذا كنت تريد فقط معالجة أول حلقة تغيير الملف إلى (files, callback) => callback(null, files[0]) وإلا فستحتاج إلى checkFiles ، readData و modify توقع مصفوفات (أو أنشئ شلالًا ثانيًا)

لن أصلح كل التعليمات البرمجية الخاصة بك ، ولكن هذه هي الطريقة التي 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);
      });
   },

....

هذا جيد.

فقط اعلم أن هذا يعمل حتى 6.2.2 ، لذا فإن أيًا كان سبب عدم عمل الكود الخاص بي قد يتسبب في عدم عمل رمز الأشخاص الآخرين.

الغريب أن الشيء الوحيد الذي يجب أن يعمل هذا الرمز هو إذا كان readdir يسرد
ملف واحد (يتم كسره أيضًا لملفات 0).

هل تمانع في التحقق من إخراج readdir في كلا الإصدارين من nod
في 27 حزيران (يونيو) 2016 ، الساعة 5:55 مساءً ، كتب "Shelley Powers" [email protected] :

هذا جيد.

فقط اعلم أن هذا نجح حتى 6.2.2 ، لذا مهما كان سبب عدم قيام الكود الخاص بي
قد يتسبب العمل في عدم عمل رمز الأشخاص الآخرين.

-
أنت تتلقى هذا لأنك قمت بتعديل حالة الفتح / الإغلاق.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/caolan/async/issues/1199#issuecomment -228887866 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe/ADUIEAfvkwCmdjmkIZIjipFGYgPQ6SzYks5qQEbpgaJpZM4I_Nsg
.

يعمل هذا الرمز دائمًا مع ملفات متعددة. حسنًا ، حتى الإصدار 6.2.2 على نظام Linux.

ولكن فقط تحقق من نظام التشغيل Windows. نعم ، عملت مع أربعة ملفات.

إخراج readdir هو ['data1.txt' ، 'data2.txt' ، 'data3.txt' ، 'data4.txt']

الإدخال إلى loopFiles هو نفسه.

في ذلك الوقت ، مع forEach ، يحصل كل رد على اسم ملف فردي.

إذا واجهت جدارًا من الطوب باستخدام المصفوفة ، فلن أستخدم هذا النهج. لكنها عملت دائما.

لا مشكلة كبيرة ، يمكنني دائمًا تحديث الكود لإزالة معالجة الصفيف. المشكلة الحقيقية هي أنه يعمل في بيئة واحدة ولكن ليس في بيئة أخرى. ومع ذلك ، فإن Node و V8 و Async هي نفس الإصدارات.

لقد قمت للتو بتشغيل كود معدل قليلاً في Ubuntu 16.04 في العقدة 6.0.0 و 6.2.2. في كلتا الحالتين حصلت على نفس النتيجة:

  • data1.txt ، رد الاتصال للعنصر الأول (data1.txt)
  • خطأ: تم استدعاء رد الاتصال بالفعل

برنامج نصي معدل:

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

لكنك لم تجربها في Windows.

بالتأكيد ، سأغلقها باعتبارها ليست مشكلة غير متزامنة.

يوم الاثنين ، 27 يونيو 2016 الساعة 8:20 مساءً ، Shelley Powers [email protected]
كتب:

لكنك لم تجربها في Windows.

-
أنت تتلقى هذا لأنك قمت بتعديل حالة الفتح / الإغلاق.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/caolan/async/issues/1199#issuecomment -228914233 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe/ADUIEDNwRmcEjcAnVmSCHBBIHvdM6DL3ks5qQGiwgaJpZM4I_Nsg
.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات