【发布时间】:2017-01-10 11:42:19
【问题描述】:
我正在整理一个示例,展示如何将简单的同步 Node.js 程序转换为使用 async/await 的异步版本。应该有几个中间步骤,从普通的基于回调的版本开始,然后是使用两个回调的一个,一个用于正常(解决)情况,另一个用于错误(拒绝)情况,然后会导致承诺。
每个版本的工作是创建一个空文件夹 copy(可能已经存在并且可能包含文件)并复制所有文件(称为 file1.txt 和file2.txt)在 orig 文件夹中。如果错误发生在任何应该被明确捕获的地方,打印到控制台并且程序不应继续执行。
带有正常错误优先回调的版本可以正常工作,但我遇到了拆分回调版本的问题。它只复制file2.txt,而不复制file1.txt。
这是我用于转换 fs 函数的代码:
const fs = require('fs');
fs.exists = function(path, callback) {
fs.stat(path, (err, stats) => {
if (err) {
callback(null, false);
} else {
callback(null, true);
}
});
};
function splitCallback(f) {
return (...params) => {
reject = params[params.length - 2];
resolve = params[params.length - 1];
params = params.slice(0, params.length - 2);
f(...params, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
};
}
const sfs = {};
const functionNames = ['exists', 'readdir', 'unlink', 'mkdir', 'readFile', 'writeFile'];
for (const functionName of functionNames) {
sfs[functionName] = splitCallback(fs[functionName].bind(fs));
}
这是使用这些函数的实际示例:
function handleError(err) {
console.error(err);
}
function initCopyDirectory(callback) {
sfs.exists('copy', handleError, exists => {
if (exists) {
sfs.readdir('copy', handleError, filenames => {
let fileCount = filenames.length;
if (fileCount === 0) {
callback();
}
for (const filename of filenames) {
sfs.unlink(`copy/${filename}`, handleError, () => {
fileCount--;
if (fileCount === 0) {
callback();
}
});
}
});
} else {
sfs.mkdir('copy', handleError, () => callback);
}
});
}
function copyFiles() {
// sfs.readdir('orig', handleError, filenames => {
// for (const filename of filenames) {
// console.log(filename);
// sfs.readFile(`orig/${filename}`, handleError, data => {
// console.log('reading', filename);
// sfs.writeFile(`copy/${filename}`, data, handleError, () => {
// console.log('writing', filename);
// });
// });
// }
// });
sfs.readdir('orig', handleError, filenames => {
for (const filename of filenames) {
fs.readFile(`orig/${filename}`, (err, data) => {
if (err) {
handleError(err);
} else {
sfs.writeFile(`copy/${filename}`, data, handleError, () => {});
}
});
}
});
}
function main() {
initCopyDirectory(copyFiles);
}
main();
正如这里所写,它可以正常工作(使用适用于 Windows 的 Node 版本 7.4.0),但是当我在 copyFiles 函数中交换 cmets(从而更改 readFile)时,只复制了一个文件,我得到以下输出:
file1.txt
file2.txt
reading file2.txt
writing file2.txt
writing file2.txt
有什么问题?
【问题讨论】:
标签: javascript node.js asynchronous callback ecmascript-6