Mju*_*ice 0 javascript foreach node.js
我有3个forEach循环,我希望前两个等待一个promise然后阻止执行,然后再重新开始迭代.我已经使用标记为1,2和3的console.log语句证明了这一点.
我希望控制台日志按顺序排列,如"1,2,3,1,2,3等"而不是我得到的是"1,2,1,2,1,2,1,2,1" ,2,3,3,3,3,3,3"如何使所有这些顺序?fetchCandidatesByCity是mongoose find方法,它返回一个promise.
axios.get(FEED_URL).then(data => {
let candidatesWithMessageSent = [];
data.data.jobs.forEach(job => {
console.log("1");
// console.log(candidatesWithMessageSent);
job.city.forEach(cityAndState => {
console.log("2");
let jobState = extractState(cityAndState);
let jobLocation = addSpaceAfterComma(cityAndState.toLowerCase());
let jobCity = extractCity(jobLocation);
fetchCandidatesByCity(jobCity)
.then(candidates => {
candidates.forEach((candidate, index) => {
console.log("3");
const candidateId = candidate._id.toString();
if (index <= MAX_MESSAGE_LIMIT &&
!containsUberLyft(job.title) &&
priceIsHigh(job.price) &&
!candidateHasMessage(candidatesWithMessageSent, candidateId)) {
const jobURL = `http://www.jobs2careers.com/click.php?id=${job.id}.${PUBLISHER_ID}`;
// candidate has received a job notification, so add candidate to candidatesWithMessageSent
candidatesWithMessageSent = [ ...candidatesWithMessageSent, candidateId ];
}
return;
});
})
.catch((error) => {
console.log(error);
});
});
});
Run Code Online (Sandbox Code Playgroud)
});
使用异步操作串行迭代数组的常见设计模式是使用.reduce()累积promise的位置.概括地说,它的工作原理如下:
array.reduce(function(p, item) {
return p.then(function() {
return someAsyncPromise(item);
});
}, Promise.resolve()).then(function(finalValue) {
// all done here
}).catch(function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
Promise.resolve()作为累加器的初始值传入.循环的每次迭代,然后return p.then(someOperation).
这基本上将一大堆操作链接在一起,如下所示:
Promise.resolve().then(...).then(...).then(...).then(...).then(...)
Run Code Online (Sandbox Code Playgroud)
每次.then()处理程序调用自定义函数时,它都会传递给数组的下一个迭代值,并返回一个将在下一次f调用之前等待的promise .
由于您有两个嵌套的数组迭代循环,您可以将一个嵌套在另一个内部,如下所示:
myData.reduce(function(p, nestedArray) {
return p.then(function() {
return nestedArray.reduce(function(p2, item) {
return p2.then(function() {
return someAsyncPromise(item);
});
}, Promise.resolve());
});
}, Promise.resolve()).then(function(finalVal) {
// all done here
}).catch(function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
或者,如果您没有使用来自外部的先前迭代的promise promise结果reduce(),您可以简化这样的一点:
myData.reduce(function(p, nestedArray) {
return nestedArray.reduce(function(p2, item) {
return p2.then(function() {
return someAsyncPromise(item);
});
}, p);
}, Promise.resolve()).then(function(finalVal) {
// all done here
}).catch(function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
这是Bluebird promise库使事情变得更容易的地方,因为您可以使用Promise.mapSeries()串行迭代数组并累积结果数组:
Promise.mapSeries(myData, function(nestedArray) {
return Promise.mapSeries(nestedArray, function(item) {
return someAsyncPromise(item);
});
}).then(function(results) {
// all done here
}).catch(function(err) {
// error here
});
Run Code Online (Sandbox Code Playgroud)
在所有这些场景中,您可以将最终结果累积到一个对象中,该对象成为最终承诺的已解析值,或者您可以将其用于副作用,其中您在更高范围内定义了一些其他对象,然后您完成后使用该对象.
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |