Promise 性能问题。读取文件太慢
Promise performance issue. Reading files too slow
我使用 promises 读取硬盘中的 10000 多个文件并在确切位置找到一个数字。我使用 glob 来 return 文件名,并为每个文件找到我 运行 方法 readFile(readFile returns 作为承诺)。处理完所有文件后,我可以继续我的工作。
function readFilesGlob(globPath,options,progressCallback){
return new Promise(function (fulfill, reject){
glob(globPath, options, function (err, files) {
var readPromisses=[];
for(var id in files){
readPromisses.push(readFile(files[id]));
}
Promise.all(readPromisses).then(
function(filesContents){
fulfill(filesContents)
}
);
});
});
}
所有承诺只有在一切都完成后才会完成,因此无法显示处理进度
function readFilesGlob(globPath,options,progressCallback){
return new Promise(function (fulfill, reject){
glob(globPath, options, function (err, files) {
var readPromisses=[];
for(var id in files){
readFile(files[id]).then(function(data){
//everything shows at the same time, like i was using the Promise.all
console.log(data)
})
}
//just testing the speed of the return in the console.log above
fulfill();
});
});
问题是。它太慢了,几分钟后我只有 return(或者当我失去记忆时)
我认为我使用的 promises 是错误的。有人可以给我一个更有效的例子来读取带有承诺的文件列表吗?
我认为在你的 for 循环中你需要这样的东西
readPromisses.push(
new Promise( function(y,n) { readFile(files[id]); y();} )
)
然后 readFile
将在 Promise
开始异步执行时调用。
这只是一个建议,我还没有测试过,所以你可能需要稍微调整一下。
这是骨架,也许会有帮助
var firstCall = new Promise((y, n) => setTimeout( () => y(Math.random()), 500 ));
var secondCall = (arg) => {
return new Promise((y, n) => setTimeout( () => y(Math.random() + ' ' + arg), 200 ));
}
var rejectCall = () => new Promise((y, n) => setTimeout( () => n(true), 400 ));
Promise.all([
firstCall,
secondCall('withArg'),
]).then( (data) => {
console.log( 'ALL: First Call result:', data[0]);
console.log( 'ALL: Second Call result:', data[1]);
}).catch( (err) => {
console.log( 'Promise.all caught reject or error:', err);
});
这似乎是 async 包的绝佳解决方案!
检查 each
函数:https://caolan.github.io/async/docs.html#each
示例:
// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {
// Perform operation on file here.
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// Do work to process file here
console.log('File processed');
callback();
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
我几乎在所有项目中都使用 async 包,它速度快且功能丰富 <3
备选方案:使用队列系统
设置队列系统,我使用的是kue,这样你也可以在你的'tasks'
上查看进度
如果 I/O 是问题所在,您可以将 'files' 数组拆分成块,然后将这些块链接起来。
chunks.reduce((result, chunk) => {
return Promise.all(chunk.map(file=> promiseRead(file))
.then(results => dealWithChunkResults(results)
}, Promise.resolve())
我使用 promises 读取硬盘中的 10000 多个文件并在确切位置找到一个数字。我使用 glob 来 return 文件名,并为每个文件找到我 运行 方法 readFile(readFile returns 作为承诺)。处理完所有文件后,我可以继续我的工作。
function readFilesGlob(globPath,options,progressCallback){
return new Promise(function (fulfill, reject){
glob(globPath, options, function (err, files) {
var readPromisses=[];
for(var id in files){
readPromisses.push(readFile(files[id]));
}
Promise.all(readPromisses).then(
function(filesContents){
fulfill(filesContents)
}
);
});
});
}
所有承诺只有在一切都完成后才会完成,因此无法显示处理进度
function readFilesGlob(globPath,options,progressCallback){
return new Promise(function (fulfill, reject){
glob(globPath, options, function (err, files) {
var readPromisses=[];
for(var id in files){
readFile(files[id]).then(function(data){
//everything shows at the same time, like i was using the Promise.all
console.log(data)
})
}
//just testing the speed of the return in the console.log above
fulfill();
});
});
问题是。它太慢了,几分钟后我只有 return(或者当我失去记忆时)
我认为我使用的 promises 是错误的。有人可以给我一个更有效的例子来读取带有承诺的文件列表吗?
我认为在你的 for 循环中你需要这样的东西
readPromisses.push(
new Promise( function(y,n) { readFile(files[id]); y();} )
)
然后 readFile
将在 Promise
开始异步执行时调用。
这只是一个建议,我还没有测试过,所以你可能需要稍微调整一下。
这是骨架,也许会有帮助
var firstCall = new Promise((y, n) => setTimeout( () => y(Math.random()), 500 ));
var secondCall = (arg) => {
return new Promise((y, n) => setTimeout( () => y(Math.random() + ' ' + arg), 200 ));
}
var rejectCall = () => new Promise((y, n) => setTimeout( () => n(true), 400 ));
Promise.all([
firstCall,
secondCall('withArg'),
]).then( (data) => {
console.log( 'ALL: First Call result:', data[0]);
console.log( 'ALL: Second Call result:', data[1]);
}).catch( (err) => {
console.log( 'Promise.all caught reject or error:', err);
});
这似乎是 async 包的绝佳解决方案!
检查 each
函数:https://caolan.github.io/async/docs.html#each
示例:
// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {
// Perform operation on file here.
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// Do work to process file here
console.log('File processed');
callback();
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
我几乎在所有项目中都使用 async 包,它速度快且功能丰富 <3
备选方案:使用队列系统
设置队列系统,我使用的是kue,这样你也可以在你的'tasks'
上查看进度如果 I/O 是问题所在,您可以将 'files' 数组拆分成块,然后将这些块链接起来。
chunks.reduce((result, chunk) => {
return Promise.all(chunk.map(file=> promiseRead(file))
.then(results => dealWithChunkResults(results)
}, Promise.resolve())