for(var i = 0; i < res.length;i++){
var info = res[i];
var fpath = attach_root_dir+'/'+picker_id+'/'+article_data._id+'/'+info.fileName;
dlog(fpath);//位置1
nodeRequire('fs').exists(fpath, function (exists) {
dlog(fpath);//位置2
});
}
这段代码没贴全。
大致的作用就是从数据库里面循环读取附件列表,然后根据每个附件的信息,路径,去判断这个附件的文件是否存在。
现在的问题是,位置2得到的fpath变量永远都是同一个。
也就是说,外层的fpath无法正确的传递到位置2。因为异步执行的原因。如何解决这个问题呢?
理由
理由は聞かれませんでしたが、理由を教えてください。
fpath 変数は単なる変数 (参照) であり、渡したコールバック関数は「ああ、(参照) fpath の値を取得できる」ということだけを知っています。
重要なのは、関数を渡すとき、渡されるのは未実行の関数だけであるということです。関数内には fpath という変数があり、実行されていないため、現在の値は取得されません。
非同期関数がそれを取得しようとしているとき、fpath の値はすでに最後の値になっています。
解決策
次のような質問があるとします。
リーリー解決策 1: (元の解決策)
リーリー解決策も非常に簡単です。上記のように、その時点では関数が実行されなかったので、その一部を実行する関数を作成し、別の関数を使用することができます。それを格納する変数。
解決策 2: (es6 ソリューション)
リーリーまず、
fs
モジュールにはファイルが存在するかどうかを判断する 2 つのメソッドがあります。1 つは非同期コールバック関数を持つfs.exists(path, callback)
で、もう 1 つは同期でブール値を返すfs.existsSync(path)
です。 。ここでの問題は、
fpath
がコールバック関数の外側のスコープに表示され、fpath が常に同じになることです。したがって、この問題を解決するには 2 つの方法があります:
リーリー1.
fs.existsSync(path)
を使用し、同期を使用します2. クロージャ:
は基本的なクロージャーの問題です。解決策は 2 つあります:
リーリーノード バージョン 0.x.x、ループ内に即時実行関数を記述します:
ノードのバージョンは 4.x.x より大きいです。var を let に変更します。
リーリー