简体   繁体   English

等待 promise.all 链式数组方法

[英]await promise.all chained array-methods

I need to recursively call an API to walk down child entries, and return the filtered results before continuing.我需要递归调用 API 来遍历子条目,并在继续之前返回过滤后的结果。 I was initially putting the results in an array, and then doing a .forEach , and if I found a match I needed to recurse doing so;我最初将结果放在一个数组中,然后执行.forEach ,如果找到匹配项,我需要递归这样做; however, that didn't work because of the problem described in the answer to this question .但是,由于这个问题的答案中描述的问题,这不起作用。 So, I tried to modify the answer to that question, but it's still not waiting.所以,我试图修改这个问题的答案,但它仍然没有等待。

const getDatabases = async (blockId) => {
  let databases = [];
  let childDatabases = [];
    
  const children = await getChildren(blockId);
  Promise.all(children.results
    .filter( (child) => {
      return (['child_database', 'database'].includes(child.type)
        || child.has_children === true);
    })
    .map( async (child) => {
      if (['child_database', 'database'].includes(child.type)) {
        return { id: child.id, title: child.child_database.title };
      } else {
        console.log(`Waiting on getDatabases for ${child.id}`); // 1
        childDatabases = await getDatabases(child.id);
        return false;
      }
    })  
  )
    .then((childDbs) => {
      console.log(`Got childDbs`); // 3, 4
      databases = 
        [...databases, ...childDatabases].filter(dbId => dbId !== false);
      return databases;
    })
    .catch((err) => console.log(err));

}

app.get('/api', async (req, res) => {
  const dashboardPage = await getDashboardPage();
  const databases = await getDatabases(dashboardPage);
  console.log('No longer awaiting getDatabases'); // 2
  ...
}

So the question is, why is 2 happening before 3 and 4, instead of after them?所以问题是,为什么 2 发生在 3 和 4 之前,而不是在它们之后? Shouldn't const databases = await getDatabases(dashboardPage);不应该const databases = await getDatabases(dashboardPage); before 2 be waiting for all the recursive calls that pass through childDatabases = await getDatabases(child.id);在 2 之前等待所有通过childDatabases = await getDatabases(child.id);的递归调用after 1? 1 之后?

The direct answer was that I needed to await the Promise.all .直接的答案是我需要await Promise.all Otherwise, the Promise.all is hanging out and waiting for the async/await inside of it, before it gets to the .then , but the parent function just fires off those promises and returns nothing, because no one told it to wait.否则, Promise.all在到达.then之前会挂出并等待其内部的async/await ,但父 function 只是触发了这些承诺并且什么也不返回,因为没有人告诉它等待。 So, simply,所以,简单地说,

const getDatabases = async (blockId) => {
  let databases = [];
  let dbsOfChildren = [];

  const children = await getChildren(blockId);
  await Promise.all(children.results
    .filter( (child) => {

It's worth noting that for similar reasons, one can not chain more array methods after an async one.值得注意的是,出于类似的原因,不能在async方法之后链接更多数组方法。 Otherwise, the next chained method will be immediately passed an array... of unresolved promises.否则,下一个链式方法将立即传递一个数组......未解决的承诺。 So, you can't, for example,所以,你不能,例如,

  await Promise.all(myArray
    .filter( (e) => {
      // do stuff
    })
    .map( async (e) => { 
      // do some async stuff
    })
    .filter( // filter ); // <-- this won't work
  )

Instead, you need to wait for the promises to resolve and then do your additional manipulations, so you put it in a .then :相反,您需要等待 promise 解决,然后进行额外的操作,因此您将其放在.then中:

  await Promise.all(myArray
    .filter( (e) => {
      // do stuff
    })
    .map( async (e) => { 
      // do some async stuff
    })
  )
  .then((myPromisesAreResolvedArray) => {
    return myMyPromisesAreResolvedArray.filter( // filter ); 
  })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM