下一个代码块在获取之前更早执行

时间:2019-04-12 03:31:30

标签: javascript node.js firebase

它应该没有给我零输出,但我却得到了空输出。如果我在代码块内部进行控制台操作,则效果很好,但在代码块外部却给出了空值 这是代码:

app.post("/downloadDb",async (req,res)=>{
 var docData = [];
 var idList = [];
  console.log("downloadBd");
  const mahafuzCol = firestore.collection("Mahafuz")
  await mahafuzCol.listDocuments()
  .then( listDoc=>{
   //List of id fetch 

    listDoc.forEach(data=>{
      idList.push(data.id)
    });
  }).catch(e=>console.log(e));


  //document is fetched 
  await idList.forEach(id=>{
    mahafuzCol.doc(id).get().then(
      doc=>{
        docData.push(doc.data());
        //Here I get desire output w=if I log with console
      }
    );
  });

//Here I get null output
  await console.log(docData);
});

2 个答案:

答案 0 :(得分:0)

因为forEach本质上是异步的,所以只要在forEach()循环中编写一个promise即可。下一条命令被执行,在您的情况下为:

new_list = []
f = open("rankings.txt", "r")
for x in f:
    temp = x.split(";")
    new_list.append(int(temp[1]))

此任务需要典型的for循环:

尝试以下代码段:

const { queryByText } = render(
    <Route path="/card/:cardId">
      <EditCard />
    </Route>,
    {
      route: '/card/1554990887217',
    }
  );

答案 1 :(得分:0)

好吧,看看您的代码,我想指出一些事情。

  1. 您正在使用最新且功能最强大的ES7异步等待功能。您为什么坚持使用旧的定义变量的方法?尝试使用let和const代替var。请勿将ECMAScript版本混在一起。这被认为是不好的做法。

  2. 到目前为止,Node.js中的循环是同步的(尽管异步循环在Node的管道中,我们很快就会看到它们)。您不能将异步代码放入循环中并期望它们按预期工作。 Node.js中有event loop的整个概念,以及Node如何处理异步任务。因此,如果您有时间,则一定要仔细研究event loop的概念。

这是编写代码的更好方法:

app.post('/downloadDb', async (req, res) => {
  // always wrap asynchronous code in async/await in try/catch blocks
  console.log('downloadBd');

  const mahafuzCol = firestore.collection('Mahafuz');

  try {
    // assuming that listDocuments returns a promise
    // await on it until it gets resolved
    // all the listed documents will be assigned to docs
    // once the promise is resolved
    const docs = await mahafuzCol.listDocuments();

    const idList = docs.map(data => data.id);

    // again assuming that get() returns a promise
    // pushing all the promises to an array so that
    // we can use Promise.all to resolve all the promises
    // at once
    const promisesList = idList.map(id => mahafuzCol.doc(id).get());

    // fetching document is here
    // once all the promises are resolved, data contains
    // the result of all the promises as an array
    const data = await Promise.all(promisesList);

    const docData = data.map(doc => doc.data());

    console.log(docData);

    // return some response
    return res.status(200).send();
  } catch (error) {
    console.log('error: ', error);

    // return some response
    return res.status(500).send();
  }
});

PS: 如果您仍然想以某种方式使用异步循环,请查看此库 https://caolan.github.io/async/docs.html#each