我使用递归函数从外部源获取数据,处理它并在必要时进行其他调用。
我需要在连续多次调用此外部源之前暂停。
在调用我的" final"之前,如何确保我拥有外部资源的所有结果?功能
function showAll(results) {
console.log('All done, time for doing something else with results')
console.log(results)
}
function checkName(person) {
console.log('checking name of ' + person.name)
if (person.name === 'Julie') return true
}
function checkPersons(url) {
// Do something here to get new data from an external source
var data = {
// 'goAgain': https://newUrl.com,
'results': [
{name: 'Bob', age: 21},
{name: 'Frank', age: 15, go: 1},
{name: 'Julie', age: 12}
]
}
var persons = data.results
var results = []
persons.forEach(function(person, i) {
if (person.age >= 18) {
console.log('do not need to check name of ' + person.name)
results.push(person)
} else {
setTimeout(function() {
if (checkName(person)) {
console.log('Julie is ' + person.name)
results.push(person)
}
}, 5000 * i)
}
})
if (data.goAgain) {
// Go back and call the function again to get the
// next set of results from external source
// checkPersons(goAgain)
console.log('Calling the function again to get more results if necessary')
} else {
// But, checkName is still running because of setTimeout
// so results doesn't yet have everything we need
showAll(results)
}
}
checkPersons('https://someurl.com')
https://jsfiddle.net/nicholasduffy/28Lpsgbj/3/
do not need to check name of Bob
// No, clearly not all done because we haven't checked Frank or Julie yet
(index):27 All done, time for doing something else with results
// Just Bob
(index):28 [Object]
(index):32 checking name of Frank
(index):32 checking name of Julie
(index):57 Julie is Julie
// Now I really want results
答案 0 :(得分:1)
您需要处理等待异步操作。一个好方法是使用Promises
。此外,即使您不需要等待setTimeout
,也可以像处理所有一样。这使您的流程更容易维护:
var promises = persons.map(function(person, i) {
return new Promise(function(resolve, reject) {
if (person.age >= 18) {
console.log('do not need to check name of ' + person.name)
results.push(person);
return resolve();
}
setTimeout(function() {
if (checkName(person)) {
console.log('Julie is ' + person.name)
results.push(person);
}
resolve();
}, 5000 * i)
});
})
Promise.all(promises)
.then(function() {
if (data.goAgain) {
// Go back and call the function again to get the
// next set of results from external source
// checkPersons(goAgain)
console.log('Calling the function again to get more results if necessary')
} else {
// But, checkName is still running because of setTimeout
// so results doesn't yet have everything we need
showAll(results)
}
});