回调与基于 promise 的操作的顺序
例如,以下内容容易出错,因为 fs.stat()
操作可能会在 fs.rename()
操作之前完成:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
});
const fs = require('fs').promises;
(async function(from, to) {
try {
await fs.rename(from, to);
const stats = await fs.stat(to);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
})('/tmp/hello', '/tmp/world');
There is no guaranteed ordering when using either the callback or
promise-based methods. For example, the following is prone to error
because the fs.stat()
operation might complete before the fs.rename()
operation:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
To correctly order the operations, move the fs.stat()
call into the callback
of the fs.rename()
operation:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
});
Or, use the promise-based API:
const fs = require('fs').promises;
(async function(from, to) {
try {
await fs.rename(from, to);
const stats = await fs.stat(to);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
})('/tmp/hello', '/tmp/world');