用setTimeoutrecursion函数

我使用recursion函数从外部源获取数据,处理它并在必要时进行其他调用。

我需要在连续多次调用这个外部源之前暂停。

在调用我的“最终”函数之前,如何确保从外部资源获得所有结果?

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 

您需要处理等待asynchronous操作。 一个很好的方法是使用Promises 。 另外,即使你不需要等待setTimeout ,也可以像处理它们一样处理它们。 这使得你的stream程更容易维护:

 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) } });