Какую версию 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
if (fn === null) throw new Error («Обратный вызов уже был вызван.»);
^
Ошибка: обратный вызов уже был вызван.
Функция обратного вызова в следующем разделе кода
function loopFiles (файлы, обратный вызов) {
files.forEach (функция (имя) {
обратный вызов (ноль, имя);
});
},
Теряется на втором заходе.
Я успешно запустил этот код в нескольких версиях Node. Думаю, я тестировал это, когда впервые был выпущен Node 6.
Во второй итерации функция не равна нулю, но что-то происходит в асинхронном коде, что приводит к этой ошибке.
Потому что вы здесь много раз вызывали обратный вызов:
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.
Просто к сведению, async.forEach не работает. Не вылетает, но и не работает.
function loopFiles(files, callback) {
async.forEach(files, function (name, callback) {
callback (null, name);
});
},
И, честно говоря, я не уверен, что проблема в forEach. Если я использую неправильно, дайте мне знать.
Хорошо, я сдаюсь.
Я обновил свой компьютер с Windows до версии 6.2.2, и этот код работает. Но на моей Linux-машине это не работает. Оба построены на одном и том же двигателе V8. Оба используют одну и ту же версию Async. Оба имеют одинаковые каталоги файлов примеров.
В Linux выдается ошибка. В Windows нет.
@shelleyp ваш водопад неправильно структурирован для нескольких файлов. Я думаю, вы хотите разделить его на два водопада или сделать так, чтобы каждый шаг ожидал массива.
Причина, по которой ваше изменение async.forEach
не сработало, заключается в том, что вы не вызываете обратный вызов loopFiles
. Эта функция в любом случае не выполняет то, что вы хотите, если вы хотите обработать только firstFile change 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 г. в 17:55 «Шелли Пауэрс» [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.
Но только что проверил на винде. Ага, работал с четырьмя файлами.
Вывод readdir: ['data1.txt', 'data2.txt', 'data3.txt', 'data4.txt']
вход в loopFiles такой же.
В этот момент с forEach каждый обратный вызов получает индивидуальное имя файла.
Если бы я когда-нибудь столкнулся с кирпичной стеной с массивом, я бы не использовал этот подход. Но это всегда срабатывало.
Нет ничего страшного, я всегда могу обновить код, чтобы убрать обработку массива. Реальная проблема в том, что он работает в одной среде, но не работает в другой. Тем не менее, Node, V8 и Async - это одни и те же версии.
Я только что запустил слегка измененный код в Ubuntu 16.04 в узлах 6.0.0 и 6.2.2. В обоих случаях я получил одинаковый результат:
Измененный скрипт:
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
Но в винде вы не пробовали.
Конечно, я закрываю это как не асинхронную проблему.
В понедельник, 27 июня 2016 г., в 20:20, Шелли Пауэрс [email protected]
написал:
Но в винде вы не пробовали.
-
Вы получаете это, потому что изменили состояние открытия / закрытия.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/caolan/async/issues/1199#issuecomment -228914233 или отключить звук
нить
https://github.com/notifications/unsubscribe/ADUIEDNwRmcEjcAnVmSCHBBIHvdM6DL3ks5qQGiwgaJpZM4I_Nsg
.