使用 q promises with map 获取文件内容
Using q promises with map to get file contents
我正在尝试使用 q
promise 库获取目录中 .json
个文件的名称和 return 这些文件的内容。我能够获取文件名,但我无法将 arr.map
与 promises 结合使用以读取文件的 contents。我想要 getContents()
到 return 一个包含指定文件名内容的映射数组。
function readDir() {
var deferred = q.defer();
fs.readdir('users', function(err, data) {
if (err) console.log(err);
deferred.resolve(data);
})
return deferred.promise;
}
function getContents(filenames) {
return filenames.map(function(filename) {
fs.readFile('users/' + filename, 'utf8', function(err, result) {
return result;
});
});
}
readDir()
.then(getContents)
.then(function(fileContents) {
// currently returns undefined
console.log(fileContents);
});
如何正确地将 getConents()
包装在一个 promise 中,以使我的数组的内容不等于 undefined?
首先,您需要获得一组承诺 - return result
在异步回调中是无用的。为每一个 readFile
电话做出承诺:
filenames.map(function(filename) {
return Q.nfcall(fs.readFile, 'users/' + filename, 'utf8');
// ^^^^^^ here's where the return is needed
})
Q.nfcall
function 基本上与您在 readDir
函数中编写的内容相同。
现在您已经有了一组承诺,您可以使用 Q.all
:
轻松地将其转换为一个数组承诺(等待所有承诺)
function getContents(filenames) {
return Q.all(filenames.map(function(filename) {
return Q.nfcall(fs.readFile, 'users/' + filename, 'utf8');
}));
}
首先,您可以使用 promises 定义 fs.readFile
的正确异步版本:
function readFileAsync(/* ...args */) {
return Q.nfapply(fs.readFile, arguments);
}
之后,您有两个选择。这将并行读取文件:
function getContents(filenames) {
return Q.all(
filenames.map(function(filename) {
return readFileAsync('users/' + filename, 'utf8');
})
);
}
这将一一阅读:
function qMap(array, selector) {
var i = 0;
var result = [];
function store(x) {
result.push(x);
return next();
}
function next() {
if (i < array.length) {
var index = i++;
var item = array[index];
return Q.fcall(selector, item, index).then(store);
} else {
return result;
}
}
return Q.fcall(next);
}
function getContents(filenames) {
return qMap(filenames, function(filename) {
return readFileAsync('users/' + filename, 'utf-8');
});
}
我正在尝试使用 q
promise 库获取目录中 .json
个文件的名称和 return 这些文件的内容。我能够获取文件名,但我无法将 arr.map
与 promises 结合使用以读取文件的 contents。我想要 getContents()
到 return 一个包含指定文件名内容的映射数组。
function readDir() {
var deferred = q.defer();
fs.readdir('users', function(err, data) {
if (err) console.log(err);
deferred.resolve(data);
})
return deferred.promise;
}
function getContents(filenames) {
return filenames.map(function(filename) {
fs.readFile('users/' + filename, 'utf8', function(err, result) {
return result;
});
});
}
readDir()
.then(getContents)
.then(function(fileContents) {
// currently returns undefined
console.log(fileContents);
});
如何正确地将 getConents()
包装在一个 promise 中,以使我的数组的内容不等于 undefined?
首先,您需要获得一组承诺 - return result
在异步回调中是无用的。为每一个 readFile
电话做出承诺:
filenames.map(function(filename) {
return Q.nfcall(fs.readFile, 'users/' + filename, 'utf8');
// ^^^^^^ here's where the return is needed
})
Q.nfcall
function 基本上与您在 readDir
函数中编写的内容相同。
现在您已经有了一组承诺,您可以使用 Q.all
:
function getContents(filenames) {
return Q.all(filenames.map(function(filename) {
return Q.nfcall(fs.readFile, 'users/' + filename, 'utf8');
}));
}
首先,您可以使用 promises 定义 fs.readFile
的正确异步版本:
function readFileAsync(/* ...args */) {
return Q.nfapply(fs.readFile, arguments);
}
之后,您有两个选择。这将并行读取文件:
function getContents(filenames) {
return Q.all(
filenames.map(function(filename) {
return readFileAsync('users/' + filename, 'utf8');
})
);
}
这将一一阅读:
function qMap(array, selector) {
var i = 0;
var result = [];
function store(x) {
result.push(x);
return next();
}
function next() {
if (i < array.length) {
var index = i++;
var item = array[index];
return Q.fcall(selector, item, index).then(store);
} else {
return result;
}
}
return Q.fcall(next);
}
function getContents(filenames) {
return qMap(filenames, function(filename) {
return readFileAsync('users/' + filename, 'utf-8');
});
}