回调和基于 promise 的操作的顺序
¥Ordering of callback and promise-based operations
因为它们是由底层线程池异步地执行,所以当使用回调或基于 promise 的方法时无法保证顺序。
¥Because they are executed asynchronously by the underlying thread pool, there is no guaranteed ordering when using either the callback or promise-based methods.
例如,以下内容容易出错,因为 fs.stat()
操作可能会在 fs.rename()
操作之前完成:
¥For example, the following is prone to error because the fs.stat()
operation might complete before the fs.rename()
operation:
const fs = require('node:fs');
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)}`);
});
通过在调用另一个之前等待前一个的结果来正确地排序操作,这是很重要的:
¥It is important to correctly order the operations by awaiting the results of one before invoking the other:
import { rename, stat } from 'node:fs/promises';
const oldPath = '/tmp/hello';
const newPath = '/tmp/world';
try {
await rename(oldPath, newPath);
const stats = await stat(newPath);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
const { rename, stat } = require('node:fs/promises');
(async function(oldPath, newPath) {
try {
await rename(oldPath, newPath);
const stats = await stat(newPath);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
})('/tmp/hello', '/tmp/world');
或者,当使用回调 API 时,将 fs.stat()
调用移动到 fs.rename()
操作的回调中。
¥Or, when using the callback APIs, move the fs.stat()
call into the callback
of the fs.rename()
operation:
import { rename, stat } from 'node:fs';
rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
});
const { rename, stat } = require('node:fs/promises');
rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
});