Javascript Promise在代码块完成之前解析
我正在使用Jimp创建图像。在执行下一个代码块之前,我需要等待所有图像都被创建 以下是我的脚本和服务器代码:Javascript Promise在代码块完成之前解析,javascript,node.js,promise,fs,Javascript,Node.js,Promise,Fs,我正在使用Jimp创建图像。在执行下一个代码块之前,我需要等待所有图像都被创建 以下是我的脚本和服务器代码: //server.js var exportImages = () => { ImageProcessor.createImage( request.body.templatePath, request.body.bitPath, request.body.exportPath ).then((m
//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();
processor.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
首先,内心的承诺。forEach永远不会被等待 其次,当Promises executor内部调用的函数返回一个Promise时,构造一个新的Promise-这是一个反模式 像下面这样的东西应该适合你
createImage: (templatePath, bitPath, activePath) => {
var jimpBit = new Jimp(bitPath, (err, img) => err ? console.log("error loading bit: " + err) : console.log("Bit loaded"));
let randomId = Math.floor(Math.random() * 100000) + 1;
activePath = './active/' + randomId + '/';
return fsPromises.readdir(templatePath)
.then((templateImages) => Promise.all(templateImages.map((templateImage, index) => {
templateImage = './raw/template1/' + templateImage;
var activeImage = activePath + randomId + '-' + index + '.PNG';
return Jimp.read(templateImage)
.then((template) => (template.clone().write(activeImage)))
.then(() => (Jimp.read(activeImage)))
.then((temporaryImage) => temporaryImage
.composite(jimpBit, 50, 50)
.composite(jimpBit, 150, 150)
.writeAsync(activeImage) // *** writeAsync ***
).then(() => console.log("Wrote image: " + activeImage))
.catch((err) => {
throw "Error with Jimp: " + err.message;
});
})))
.then(() => activePath)
.catch((err) => {
throw "Error reading files from " + templatePath + "\n" + err.message;
});
}
使用Promise.all代替forEach,并在Promise.all返回响应后解析Promise。想法:将.forEach更改为常规for循环,并在teach中的异步操作上使用wait。现在的问题是,forEach不等待内部的任何承诺,因此它在循环中的任何承诺完成之前就完成了循环,因此您调用resolve的时间太早了。你也不需要用新的承诺来包装它,因为一旦你将内部承诺添加到承诺链中,你就可以返回你已经拥有的承诺链。为什么你要构建一个承诺,其中调用的函数返回一个承诺?在创建图像之前,我仍然会得到相同的输出到达final-then-block。调用函数时没有任何更改,对吗?@raney24抱歉,我可能错过了一次返回-在我尝试修复它之前,temporaryImage.CompositeImpBit,50,50.CompositeImpBit,150,150.writeactiveImage是否返回承诺?它甚至是异步的吗?我现在明白了。。。如果使用.writeAsync而不是.write,它将返回一个承诺-现在应该可以go@raney24-不,它不应该。。。事实上,我的版本正确地返回了activePath-您的将是一个语法错误。。。签出文档以获取