我在循环中遇到诺言问题。我需要循环进入一个js对象,其中包含有关上载媒体的信息。可以是图像,视频和音频。对于图像,我想使用jimp快速调整其大小,然后将文件保存在s3上并将信息保存在db上。问题在于脚本完成了,图像压缩之前没有错误。
我尝试了不同的方法来解决该问题,例如使用没有承诺的jimp,或者在异步函数中定义jimp,而将调整大小的结果设置为await但没有。如您所知,我使用dbg数组调试脚本,结果如下:
0: "1"
1: "2"
2: "0 3"
3: "after type condition"
4: "loop:0"
5: "1 3"
6: "after type condition"
7: "loop:1"
8: "2 3"
9: "after type condition"
10: "loop:2"
您可以看到该函数在进入jimp函数之前便已停止。
api.post('/posts/createpost', function(request) {
return new Promise((resolve, reject) => {
connectDb()
.then( () => { return savePost() } )
.then( () => { return iteratePostMedia() } )
.then( () => { conn.release() } )
.then( () => { resolve( { success : "done", audioPresigned : audioPresigned, videoPresigned : videoPresigned, postId : postId, dbg : dbg } ) } )
.catch( (err) => { reject(err) }
});
}, {
customAuthorizer: 'jwtAuth'
});
function connectDb(){
return new Promise((resolve, reject) => {
pool.getConnection(function(err, connection) {
if (err) reject(err);
conn = connection;
resolve( connection );
});
});
}
function savePost(){
return new Promise((resolve, reject) => {
dbg.push("1"); //only for debug
let sql = "INSERT INTO posts SET user_id = ?, content = ?, privacy = ?";
conn.query(sql, [userId, "the content", 1, "POINT ("+userCoordDefault+")" ], function (error, results, fields) {
if (error) {
conn.release();
reject(error);
}else{
postId = results.insertId;
dbg.push("2"); //only for debug
}
})
});
}
async function iteratePostMedia(){
let results = [];
for (let key in media) {
let r = savePostMedia(key);
results.push(r);
dbg.push("loop:"+key);
}
return results;
}
function savePostMedia(key){
return new Promise((resolve, reject) => {
if ( media[key].type == 'image'){
dbg.push(key+" 3"); //only for debug
let base64Img = media[key].file.split(',')[1];
Jimp.read( Buffer.from(base64Img, 'base64') )
.then(image => {
dbg.push(key+" 4");
console.log("then image");
image.resize( imgWidth, Jimp.AUTO ).getBuffer(Jimp.AUTO, (err, buffer) => {
dbg.push(key+" 5"); //only for debug
let fileName = uuidV1()+'.jpg';
s3.putObject( {
Bucket: myBucket,
Key: fileName,
ACL: 'public-read',
ContentType : 'image/jpeg',
Body: buffer
}, ( err, status ) => {
if ( err !== null ){ console.log('s3 put error'); reject(err); }
dbg.push(key+" 6");
let sql = "INSERT INTO media SET media_author = ?, media_type = ?, media_url = ?, media_status = ?, media_parent = ?";
conn.query(sql, [userId, 'image', fileName, 'active', postId], function (error, results, fields) {
if (error) {
conn.release();
reject(error);
}else{
resolve( console.log('image saved') );
}
})
//resolve('upload done')
});
});
})
.catch(err => {
console.log(err);
reject(err);
});
}else if ( media[key].type == 'audio' || media[key].type == 'video' ){
let ext = media[key].name.split('.').pop();
let fileName = uuidV1() + '.' + ext;
let contentType = media[key].type + '/' + ext
const params = {
Expires: 60,
Bucket: myBucket,
Conditions: [["content-length-range", 100, 200000000]], // 100Byte - 200MB
Fields: {
"Content-Type": contentType,
key: fileName
}
};
s3.createPresignedPost(params, (err, data) => {
if (err) {
reject(err);
return;
}
if ( media[key].type == 'video'){ videoPresigned = data }
if ( media[key].type == 'audio'){ audioPresigned = data }
let sql = "INSERT INTO media SET media_author = ?, media_type = ?, media_url = ?, media_status = ?, media_parent = ?";
conn.query(sql, [userId, media[key].type, fileName, 'active', postId], function (error, results, fields) {
if (error) {
conn.release();
reject(error);
}else{
resolve( console.log('video or audio saved') );
}
})
});
}
dbg.push("after type condition");
}); // end promise
}
我想遍历所有媒体以压缩并保存图像。