返回Promise.all([photoArray])返回一个空数组,似乎不等待callFB返回其诺言,然后将其推入数组。
我不确定自己在做什么错,但对于for循环和Ifs而言,它对于Promises来说相对较新。
我不确定我是否使用了正确数量的Promises,但是我似乎无法获得第三层Promise.all,以等待for循环实际完成(在这种情况下,for循环具有仔细检查许多项目,所以这引起了一个问题,即它不会在调用context.done()之前应触发的所有项目都触发callFeedback。
我也尝试将Q.all也用于Promise.all([photoArray]),但无法正常工作。
module.exports = function (context, myBlob) {
var res = myBlob
var promiseResolved = checkPhoto(res,context);
var promiseResolved2 = checkVideo(res,context);
Promise.all([promiseResolved, promiseResolved2]).then(function(results){
context.log(results[0], results[1]);
// context.done();
});
});
};
};
function checkPhoto(res, context){
return new Promise((resolve, reject) => {
if (res.photos.length > 0) {
var photoArray = [];
for (var j = 0; j < res.photos.length; j++) {
if (res.photos[j].feedbackId !== null){
var feedbackId = res.photos[j].feedbackId;
var callFB = callFeedback(context, feedbackId);
Promise.all([callFB]).then(function(results){
photoArray.push(results[0]);
});
} else {
photoArray.push("Photo " + j + " has no feedback");
}
}
return Promise.all([photoArray]).then(function(results){
context.log("end results: " + results);
resolve(photoArray);
});
} else {
resolve('No photos');
}
})
}
function checkVideo(res, context){
return new Promise((resolve, reject) => {
same as checkPhoto
})
}
function callFeedback(context, feedbackId) {
return new Promise((resolve, reject) => {
var requestUrl = url.parse( URL );
var requestBody = {
"id": feedbackId
};
// send message to httptrigger to message bot
var body = JSON.stringify( requestBody );
const requestOptions = {
standard
};
var request = https.request(requestOptions, function(res) {
var data ="";
res.on('data', function (chunk) {
data += chunk
// context.log('Data: ' + data)
});
res.on('end', function () {
resolve("callFeedback: " + true);
})
}).on('error', function(error) {
});
request.write(body);
request.end();
})
}
答案 0 :(得分:0)
该代码受promise construction antipattern的影响。如果已经有了一个承诺(Promise.all(...)
),则无需创建新的承诺。
错误的行为是由Promise.all(...).then(...)
承诺未链接引起的。错误不会得到处理,photoArray.push(results[0])
会导致竞争状况,因为它的评估晚于Promise.all([photoArray])...
。
万一应该并行处理:
function checkPhoto(res, context){
if (res.photos.length > 0) {
var photoArray = [];
for (var j = 0; j < res.photos.length; j++) {
if (res.photos[j].feedbackId !== null){
var feedbackId = res.photos[j].feedbackId;
var callFB = callFeedback(context, feedbackId);
// likely no need to wait for callFB result
// and no need for Promise.all
photoArray.push(callFB);
} else {
photoArray.push("Photo " + j + " has no feedback");
}
}
return Promise.all(photoArray); // not [photoArray]
} else {
return 'No photos';
};
}
callFB
的承诺彼此不依赖,因此可以安全地同时解决。这样可以更快地处理请求。
Promise.all
仅在用于并行解决承诺时才有用,而原始代码则尝试解决结果(results[0]
)。
如果应按顺序处理事物,则该功能将从async..await
中受益:
async function checkPhoto(res, context){
if (res.photos.length > 0) {
var photoArray = [];
for (var j = 0; j < res.photos.length; j++) {
if (res.photos[j].feedbackId !== null){
var feedbackId = res.photos[j].feedbackId;
const callFBResult = await callFeedback(context, feedbackId);
// no need for Promise.all
photoArray.push(callFBResult);
} else {
photoArray.push("Photo " + j + " has no feedback");
}
}
return photoArray; // no need for Promise.all, the array contains results
} else {
return 'No photos';
};
}
添加try..catch
来品尝。