【发布时间】:2020-02-19 06:17:25
【问题描述】:
我正在使用 Jimp 创建图像。在执行下一个代码块之前,我需要等到所有图像都创建完成。
这是我的脚本和服务器代码:
//server.js
var exportImages = () => {
ImageProcessor.createImage(
request.body.templatePath,
request.body.bitPath,
request.body.exportPath
).then((msg) => {
console.log("In the final then block");
response.send(msg);
}).catch((err) => {
response.send(err.message)
});
}
exportImages();
处理器.js
createImage: (templatePath, bitPath, activePath) => {
var jimpBit = new Jimp(bitPath, function(err, img) {
err ? console.log("error loading bit: " + err) : console.log("Bit loaded");
});
let randomId = Math.floor(Math.random() * 100000) + 1; // # 1-100000
activePath = './active/' + randomId + '/';
return new Promise( (resolve, reject) => {
fsPromises.readdir(templatePath)
.then( (templateImages ) => {
templateImages.forEach( (templateImage, index) => {
templateImage = './raw/template1/' + templateImage;
var activeImage = activePath + randomId + '-' + index + '.PNG';
Jimp.read(templateImage)
.then( (template) => (template.clone().write(activeImage)))
.then( () => (Jimp.read(activeImage)))
.then( (temporaryImage) => {
temporaryImage
.composite( jimpBit, 50, 50 )
.composite( jimpBit, 150, 150 )
.write(activeImage);
console.log("Wrote image: " + activeImage);
})
.catch( (err) => {
reject("Error with Jimp: " + err.message);
});
});
})
.then( () => {
resolve(activePath);
})
.catch( (err) => {
reject("Error reading files from " + templatePath + "\n" + err.message);
})
});
有人可以帮我理解为什么在创建图像之前调用最后一个 .then 块吗?
我的实际结果是:
In the final then block
Bit loaded
Created image: ./active/64136/64136-4.PNG
Created image: ./active/64136/64136-2.PNG
Created image: ./active/64136/64136-6.PNG
Created image: ./active/64136/64136-1.PNG
Created image: ./active/64136/64136-7.PNG
Created image: ./active/64136/64136-5.PNG
Created image: ./active/64136/64136-0.PNG
Created image: ./active/64136/64136-3.PNG
【问题讨论】:
-
使用 Promise.all 代替 forEach 并在 Promise.all 返回响应后解决一个承诺。
-
一个想法:将
.forEach更改为常规的for循环并在教学中的异步操作上使用await。现在的问题是.forEach()不等待内部的任何承诺,因此它在循环内的任何承诺完成之前很久就完成了循环,因此您调用resolve()太快了。您也不需要将其包装在new Promise()中,因为只要将内部承诺添加到链中,您就可以返回已有的承诺链。 -
你为什么要构造一个 Promise,而它内部调用的函数返回一个 Promise?
标签: javascript node.js promise fs