首页 > 解决方案 > 在获取之前执行下一个代码块我该如何解决

问题描述

它应该给我的不是空输出,但我得到的是空输出。如果我在代码块内部进行控制台,但在外部给我空值,它工作正常这是代码:

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

标签: javascriptnode.jsfirebase

解决方案


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

  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


推荐阅读