因为从 Promise 执行器内部与外部世界“通信”的唯一方法是使用resolve
和reject
函数。您可以使用以下示例:
function fn() {
return new Promise(async (resolve, reject) => {
// there is no real reason to use an async executor here since there is nothing async happening
try {
throw new Error('<<fn error>>')
} catch(error) {
return reject(error);
}
});
}
例如,当您想做一些具有方便的异步功能但也需要回调的事情时。以下人为示例通过使用异步fs.promises.readFile
函数和基于回调的fs.writeFile
函数读取文件来复制文件。在现实世界中,您永远不会混合这样的fs
函数,因为没有必要。但是一些库,如 stylus 和 pug 使用回调,我在这些场景中一直使用这样的东西。
const fs = require('fs');
function copyFile(infilePath, outfilePath) {
return new Promise(async (resolve, reject) => {
try {
// the fs.promises library provides convenient async functions
const data = await fs.promises.readFile(infilePath);
// the fs library also provides methods that use callbacks
// the following line doesn't need a return statement, because there is nothing to return the value to
// but IMO it is useful to signal intent that the function has completed (especially in more complex functions)
return fs.writeFile(outfilePath, data, (error) => {
// note that if there is an error we call the reject function
// so whether an error is thrown in the promise executor, or the callback the reject function will be called
// so from the outside, copyFile appears to be a perfectly normal async function
return (error) ? reject(error) : resolve();
});
} catch(error) {
// this will only catch errors from the main body of the promise executor (ie. the fs.promises.readFile statement
// it will not catch any errors from the callback to the fs.writeFile statement
return reject(error);
// the return statement is not necessary, but IMO communicates the intent that the function is completed
}
}
}
显然每个人都说这是一种反模式,但是当我想在做一些只能用回调完成的事情之前做一些异步的事情时,我一直使用它(而不是像我人为的例子那样复制文件)。我不明白为什么人们认为这是一种反模式(使用异步Promise执行器),并且还没有看到一个例子让我相信它应该被接受为一般规则。