Для цикла и асинхронного обратного вызова в node.js?
Я новичок в JavaScript и node.js. Я хочу прокрутить каталог и добавить в файл весь файл stat (не другие каталоги). Как вы видите ниже, проблема связана с моим кодом, так как обратный вызов, вероятно, будет вызван после завершения цикла for, поэтому использование "i" -переменная в методе обратного вызова не будет работать. Но как код должен выглядеть так, как работает нижеприведенный фрагмент? Это имеет какое-то отношение к закрытию?
Спасибо за помощь!
fs.readdir(SYNCDIR, function(err1, files) {
var filesOnly = [];
if(!err1) {
for(var i = 0; i < files.length; i++) {
var imgFilePath = SYNCDIR + '/' + files[i];
fs.stat(imgFilePath, function(stat){
if (stat.isFile()){
filesOnly[i] = stat; // This will not be correct since the for-loop has finished
}
});
}
}
});
Ответы
Ответ 1
Вы правы в том, что нужно использовать закрытие. Вы должны обернуть содержимое цикла for
в функцию самозапускания, чтобы сохранить значение i
для каждой итерации.
fs.readdir(SYNCDIR, function(err1, files) {
var filesOnly = [];
if(!err1) {
for(var i = 0; i < files.length; i++) {
(function(i) {
var imgFilePath = SYNCDIR + '/' + files[i];
fs.stat(imgFilePath, function(stat){
if (stat.isFile()){
filesOnly[i] = stat;
}
});
})(i);
}
}
});
Ответ 2
Один из способов - переписать внутренности цикла для использования замыкания:
fs.readdir(SYNCDIR, function(err1, files) {
var filesOnly = [];
if(!err1) {
for(var i = 0; i < files.length; i++) {
(function(index) {
var imgFilePath = SYNCDIR + '/' + files[index];
fs.stat(imgFilePath, function(stat){
if (stat.isFile()){
filesOnly[index] = stat;
}
});
})(i);
}
}
});
Лучше выглядящий пример, достигнув того же, используя Array.prototype.forEach:
fs.readdir(SYNCDIR, function(err1, files) {
var filesOnly = [];
if(!err1) {
files.forEach(function(file, i) {
var imgFilePath = SYNCDIR + '/' + file;
fs.stat(imgFilePath, function(stat){
if (stat.isFile()){
filesOnly[i] = stat;
}
});
});
}
});
Ответ 3
В качестве альтернативы используйте новый модуль потоков (https://github.com/robtweed/Q-Oper8), а затем вы можете сделать все это намного проще, используя стандартное синхронное кодирование в пределах потоки дочерних процессов, поскольку они обрабатывают только один запрос пользователя за раз.
До свидания с асинхронной логикой и вложенными обратными вызовами!