どのバージョンの非同期を使用していますか?
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( "コールバックはすでに呼び出されました。");
^
エラー:コールバックはすでに呼び出されています。
コードの次のセクションのコールバック関数
関数loopFiles(ファイル、コールバック){
files.forEach(関数(名前){
コールバック(null、名前);
});
}、
2回目の実行で失われます。
このコードは、Nodeのいくつかのバージョンで正常に実行されました。 ノード6が最初にリリースされたときにこれをテストしたと思います。
2回目の反復では、関数はnullではありませんが、非同期コードで何かが発生しているため、このエラーが発生します。
ここで何度もコールバックを呼び出したため:
function loopFiles(files, callback) {
files.forEach(function(name) {
callback(null, name);
});
},
この場合はasync.forEachを使用してください。
面白い。 以前のバージョンのNodeで問題は発生していません。実際、これはWindowsマシンのNode6.0.0で正常に実行されました。
そのため、6.0.0と6.2.2の間で何かが変更され、組み込みのforEachを使用するとAsyncが機能しなくなりました。
参考までに、async.forEachは機能しません。 クラッシュしませんが、機能しません。
function loopFiles(files, callback) {
async.forEach(files, function (name, callback) {
callback (null, name);
});
},
率直に言って、問題の原因がforEachであるかどうかはわかりません。 間違って使用している場合は、お知らせください。
OK、あきらめます。
Windowsマシンを6.2.2に更新しましたが、このコードは機能します。 しかし、私のLinuxマシンでは動作しません。 どちらも同じV8エンジンで構築されています。 どちらも同じバージョンの非同期を使用しています。 どちらにも同じサンプルファイルディレクトリがあります。
Linuxでは、エラーがスローされます。 Windowsではそうではありません。
@shelleypウォーターフォールは、複数のファイルに対して不適切に構造化されています。 それを2つの滝に分けるか、各ステップに配列を期待させたいと思います。
async.forEach
変更が機能しなかった理由は、 loopFiles
コールバックを呼び出していないためです。 firstFileを処理するだけの場合、その関数はとにかく期待どおりに機能しません。loopFilesを(files, callback) => callback(null, files[0])
変更します。それ以外の場合は、 checkFiles
、 readData
が必要になります。 modify
は配列を期待します(または2番目のウォーターフォールを作成します)
すべてのコードを修正するつもりはありませんが、これが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がリストされている場合だけです。
1つのファイル(0ファイルの場合も壊れます)。
両方のバージョンのnodでreaddirの出力を再確認してもかまいません
2016年6月27日午後5時55分、「ShelleyPowers」 [email protected]は次のように書いています。
それはいいです。
これは6.2.2まで機能したことを知っているので、私のコードが機能しなくなった原因は何でも
作業すると、他の人のコードが機能しなくなる可能性があります。—
開/閉状態を変更したため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/caolan/async/issues/1199#issuecomment -228887866、またはミュート
スレッド
https://github.com/notifications/unsubscribe/ADUIEAfvkwCmdjmkIZIjipFGYgPQ6SzYks5qQEbpgaJpZM4I_Nsg
。
このコードは常に複数のファイルで機能します。 ええと、Linuxでは6.2.2まで。
しかし、Windowsでチェックしただけです。 うん、4つのファイルで動作しました。
readdirの出力は['data1.txt'、 'data2.txt'、 'data3.txt'、 'data4.txt']です。
loopFilesへの入力は同じです。
その時点で、forEachを使用すると、各コールバックは個別のファイル名を取得します。
アレイでレンガの壁にぶつかったことがあれば、このアプローチは使用しなかったでしょう。 しかし、それは常に機能しました。
大したことではありません。いつでもコードを更新して配列処理を削除できます。 本当の問題は、ある環境では機能しますが、別の環境では機能しないことです。 ただし、Node、V8、およびAsyncは同じバージョンです。
Ubuntu16.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
しかし、あなたはそれをWindowsで試していませんでした。
確かに、非同期の問題ではないため、クローズします。
20:20時月、2016年6月27日には、シェリーパワーズ[email protected]
書きました:
しかし、あなたはそれをWindowsで試していませんでした。
—
開/閉状態を変更したため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/caolan/async/issues/1199#issuecomment -228914233、またはミュート
スレッド
https://github.com/notifications/unsubscribe/ADUIEDNwRmcEjcAnVmSCHBBIHvdM6DL3ks5qQGiwgaJpZM4I_Nsg
。