我试图理解为什么以下承诺设置不起作用。
(注意:我已经用 async.map 解决了这个问题。但我想了解为什么我在下面的尝试没有奏效。)
正确的行为应该是:bFunc 应该运行尽可能多的时间以 fs 读取所有图像文件(下面的 bFunc 运行两次),然后 cFunc 控制台打印“结束”。
谢谢!
尝试 1:它在 cFunc() 处运行并停止。
var fs = require('fs');
bFunc(0)
.then(function(){ cFunc() }) //cFunc() doesn't run
function bFunc(i){
return new Promise(function(resolve,reject){
var imgPath = __dirname + "/image1" + i + ".png";
fs.readFile(imgPath, function(err, imagebuffer){
if (err) throw err;
console.log(i)
if (i<1) {
i++;
return bFunc(i);
} else {
resolve();
};
});
})
}
function cFunc(){
console.log("End");
}
尝试 2:在这种情况下,我使用了一个 for 循环,但它执行无序。控制台打印:结束,bFunc 完成,bFunc 完成
var fs = require('fs');
bFunc()
.then(function(){ cFunc() })
function bFunc(){
return new Promise(function(resolve,reject){
function read(filepath) {
fs.readFile(filepath, function(err, imagebuffer){
if (err) throw err;
console.log("bFunc done")
});
}
for (var i=0; i<2; i++){
var imgPath = __dirname + "/image1" + i + ".png";
read(imgPath);
};
resolve()
});
}
function cFunc(){
console.log("End");
}
我在这里先向您的帮助表示感谢!
原文由 David 发布,翻译遵循 CC BY-SA 4.0 许可协议
因此,每当您有多个异步操作以某种方式进行协调时,我立即想要去承诺。而且,使用 Promise 协调多个异步操作的最佳方式是让每个异步操作都返回一个 Promise。您显示的最低级别的异步操作是
fs.readFile()
。由于我使用 Bluebird Promise 库,它具有“承诺”整个模块的异步函数价值的功能。这将在
fs
对象上创建新的并行方法,该对象带有“异步”后缀,返回承诺而不是使用直接回调。所以,会有一个fs.readFileAsync()
返回一个承诺。您可以 在此处 阅读有关 Bluebird 承诺的更多信息。因此,现在您可以创建一个相当简单的函数来获取图像并返回一个其值是图像数据的承诺:
然后,在您的代码中,您似乎想让
bFunc()
成为读取其中三个图像并在完成后调用cFunc()
的函数。你可以这样做:如果您不想使用 Bluebird,您可以手动制作
fs.readFile()
的承诺版本,如下所示:或者,在 node.js 的现代版本中,您可以使用
util.promisify()
来制作遵循 node.js 异步调用约定的函数的承诺版本:不过,您很快就会发现,一旦开始使用 Promise,您就会希望将它们用于所有异步操作,因此您将“承诺”很多事情,并拥有一个库或至少一个通用函数可以为您做到这一点节省大量时间。
在更新版本的 node.js(版本 10.0+)中,您可以使用支持承诺的
fs
库的内置版本: