2017-08-06 88 views
-1

我有这样一个循环:如何等待一个循环的完整执行Node.js加载

var someArray = []; 

for(var i = 0; i < myArray.length; i++) { 
    var tempArray = []; 

    arangodb.query('somequery') 
     .then(
      cursor => cursor.all() 
     ).then(
      keys => tempArray = keys, 
      err => console.error('Failed to execute query:', err) 
     ).then(function() { 
      someArray.push.apply(someArray, tempArray); 
     }); 
} 

我想在所有tempArrayssomeArray收集进行其他操作。但是由于Node.js是异步的,我不知道该怎么做。你能帮助我吗?提前致谢。

+0

的node.js不ASYNC, 'arangodb.query'是 –

+0

可以'arangodb.query('somequery')'并行运行还是必须串联?另外,如果一个失败,继续处理或停止? –

+0

他们可以并行运行,如果你参考我的答案Promise.all()会拒绝,如果即使有一个承诺失败 – marvel308

回答

3

这将导致从cursor.all()

任何arangodb.querykeys扁平阵列失败将被忽略(仍与控制台输出虽然)

Promise.all(myArray.map(item => 
    arangodb.query('somequery') 
    .then(cursor => cursor.all())) 
    .catch(err => console.error('Failed to execute query:', err)) 
) 
// remove rejections, which will be undefined 
.then(results => results.filter(result => !!result)) 
// flatten the results 
.then(results => [].concat(...results)) 
.then(results => { 
    // do things with the array of results 
}) 
+0

这条线是否如下所示:'.then(results => [] .concat(... results))'?我的意思是应该有三个点? – jason

+0

是的。在es2016或是es2017。无论如何。最新的节点会喜欢它。否则使用babel –

+0

谢谢最后一个问题:在最后一部分应该是这样的:'.then(results => { someArray = results; })或者应该还有其他一些代码? – jason

1

你需要使用Promise.all()

var someArray = []; 

function queryDB(){ 
    return arangodb.query('somequery') 
     .then(
      cursor => cursor.all()).then(
      keys => tempArray = keys, 
      err => console.error('Failed to execute query:', err) 
     ).catch(function(err){ 
      console.log('Failed'); 
     }) 
} 
var promiseArray = []; 
for(var i = 0; i < myArray.length; i++) 
{ 
    promiseArray.push(queryDB()); 
} 

Promise.all(promiseArray).then(function(results){ 

    someArray = results.filter(result => !!result); 
}) 

基本上queryDB()将返回一个承诺,你可以做Promise.all()来等待所有的承诺来解决,然后你可以在结果

访问结果
+0

这不适用于失败,并可能错误地表示早期完成。从[MDN]引用(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) Promise.all fail-fast behavior Promise.all被拒绝,如果有的元素被拒绝。例如,如果您在超时后传递四个承诺并且立即拒绝一个承诺,那么Promise.all将立即拒绝。 –

+0

'tempArray'未定义,你的结果将是一个数组数组 - 你已经重写了太多的OP的意图 –

+0

@ManasJayanth,所以我应该在每次承诺后传递给'someArray'吗? – jason

1

跟踪所有异步操作是否完成的唯一方法是简单地保持成功回调触发器和失败回调触发器的计数。以下应该帮助你。

let count = 0; 

const checkCompletion = (curr, total) => { 
    if (curr < total) { 
     // Not all tasks finised 
    } else { 
     // All done 
    } 
}; 

for(var i = 0; i < myArray.length; i++) { 
    var tempArray = []; 
    arangodb.query('somequery') 
     .then(cursor => cursor.all()) 
     .then(keys => { 
      // success 
      count += 1; 
      checkCompletion(count, myArray.length); 
     }).catch(e => { 
      // failure 
      count += 1; 
      checkCompletion(count, myArray.length); 
     }); 

} 
相关问题