Javascript 如何处理嵌套循环中的承诺
我有这样一个对象数组: 聚合结果给出了具有以下相同结构的结果:Javascript 如何处理嵌套循环中的承诺,javascript,arrays,node.js,mongodb,promise,Javascript,Arrays,Node.js,Mongodb,Promise,我有这样一个对象数组: 聚合结果给出了具有以下相同结构的结果: results = [ {id: 1, test: biology, candidates:[ {cid: 11},{cid: 12},{cid: 13}]}, {id: 2, test: chemistry, candidates:[ {cid: 15},{cid: 16},{cid: 17}]}, {id: 3, test: physics, candidates:[ {cid: 1},{cid: 6},{cid:
results = [
{id: 1, test: biology, candidates:[ {cid: 11},{cid: 12},{cid: 13}]},
{id: 2, test: chemistry, candidates:[ {cid: 15},{cid: 16},{cid: 17}]},
{id: 3, test: physics, candidates:[ {cid: 1},{cid: 6},{cid: 7}]}
];
所以我需要在数组中循环,然后为每个候选调用一个promise函数getTotalMarksPerCandidate(它有一个promise.all,并在一些计算之后解析变量)。然而,由于循环在数组中,并没有等待承诺完成,我得到承诺
问题:您知道我如何解决这个问题,以便在我的候选数组中循环时,它等待结果并继续?或者有什么扭转局面的办法
所以我映射到结果数组中,然后在候选数组中执行forEach,调用函数getTotalMarksPerCandidate,将候选对象作为参数,将结果推送到promise数组中。然后将解决所有收到的承诺
var new_Result = results.map( function (subject) {
let promises = [];
if (subject.candidates && subject.candidates.length > 0) {
subject.candidates.forEach( (element) => {
promises.push(mobileUtil. getTotalMarksPerCandidate(element));
});
}
return Promise.all(promises).then( result => {
console.log('Check this out', result);
subject.newCandidatelist = result;
return subject;
});
});
console.log('R: ', new_Result);
resolve(params);
所以在return Promise.all(promissions)回调函数中,我可以看到承诺正在被解析,并且我可以看到函数getTotalMarksPerCandidate的返回值。如何将带有totalMarks的新候选对象设置为其各自的父对象
new_results = [
{id: 1, test: biology, candidates:[ {cid: 11, score: 88},{cid: 12, score: 90},
{cid: 13, score: 91}]},
{id: 2, test: chemistry, candidates:[ {cid: 15, score: 91},{cid: 16, score: 91},
{cid: 17, score: 91}]},
{id: 3, test: physics, candidates:[ {cid: 1, score: 91},{cid: 6, score: 91},
{cid: 7, score: 91}]}
];
谢谢一种完全基于嵌套的
承诺
链的方法如下:
/*
Obtain array of promises via results.map() and resolve each sequentially
*/
const new_Result = Promise.all(results.map((subject) => {
/*
Start a promise chain for this subject
*/
return Promise.resolve()
.then(() => {
/*
Get candidates from current subject, or just an empty array if no valid candidates data present
*/
const candidates = Array.isArray(subject.candidates) && subject.candidates.length > 0 ? subject.candidates : [];
/*
Map candidates (if any) to this Promise.all()
*/
return Promise.all(candidates.map((candidate) => {
return mobileUtil.getTotalMarksPerCandidate(element).then(function(score) {
/*
Assign the score returned from getTotalMarksPerCandidate() for current candidate object
*/
candidate.score = score;
/*
Return the updated candidate to mapped array of promise results
*/
return candidate;
})
}));
})
.then((result) => {
console.log('Check this out', result);
subject.newCandidatelist = result;
return subject;
});
}));
这里的关键添加是这些行,它们基本上“附加”了从getTotalMarksPerCandidate()
的解析承诺返回的分数值到当前正在迭代的候选者
:
return mobileUtil.getTotalMarksPerCandidate(element).then(function(score) {
candidate.score = score;
return candidate;
})
希望有帮助 使用async/await可以
(async () => {
try {
const new_Result = results.map(({ candidates, ...rest }) => {
const updatedCandidates = candidates.map(async candidate => {
const score = await getTotalMarksPerCandidate(candidate)
return { score, ...candidate }
})
return { candidates: updatedCandidates, ...rest }
})
console.log(new_Result)
} catch(err) {
// handle error
}
})()
感谢Dacre&Chridam&Bergi花时间回答这个问题。所以我尝试了这两种解决方案,并对Dacre解决方案进行了一些调整,它起了作用,我在前端得到了我所需要的 Params是作为参数传递给函数的json对象。 mobileUtil.getTotalMarksPerCandidate是一个被调用的函数,它返回一个对象,对象本身带有修改后的标记,最初作为参数发送
Promise.all( results.map( jobtitle => {
return Promise.resolve()
.then(() => {
const candidates = Array.isArray(subject.candidates) && subject.candidates.length > 0 ? subject.candidates : [];
/*
Map candidates (if any) to this Promise.all()
*/
if (candidates && candidates.length > 0)
{
return Promise.all(candidates.map((candidate) => {
return mobileUtil. getTotalMarksPerCandidate(candidate).then( function(candidate) {
/*
Return the updated candidate to mapped array of promise results
*/
return candidate;
})
}));
}
})
.then((result) => {
return subject;
});
})
).then( res => {
params.listofnewCandidates = res;
resolve(params);
});
只需使用另一个
承诺即可。新结果
上的所有
,这也是一个承诺数组?