簡體   English   中英

Nodejs 似乎在等待包含 Promise 的函數解析之前返回響應

[英]Nodejs appears to return a response before waiting for functions containing Promises to resolve

我正在嘗試點擊我的 API 端點“類別”以從 firebase 中的類別集合返回文檔列表。 使用以下代碼:

function getCategories() {
  let arr = [];
  categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        return arr;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

router.route("/categories").get(async function(req, res, next) {
  let arr = await getCategories();
  res.json(arr);
});

雖然我沒有收到任何錯誤,但我收到一個空響應,在調試時顯示arr未定義。 問題是當使用調試器時, forEach的控制台日志被調用,我在控制台中看到了我的類別,但由於某種原因,它不會等待 Firebase Promise 解析,路由器只是用未定義的arr變量進行響應。

您的.then回調應該更像這樣(不需要單獨的arr變量):

function getCategories() {
  // notice we are returning the promise
  return categories
    .get()
    .then(snapshot => {
      // notice we are returning the new array using .map()
      return snapshot.map(doc => {
        console.log(doc.data().category);
        return doc.data().category;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

並且由於您已經在使用 async/await,您可以將所有內容重寫為如下所示,以便您的用戶可以知道何時發生錯誤:

// notice the function is now async
async function getCategories() {
    const snapshot = await categories.get()
    // this can be a one-liner in the example above too
    return snapshot.map(doc => doc.data().category);
}

router.route("/categories").get(async function(req, res, next) {
   try {
     let arr = await getCategories();
     res.json(arr);
   } catch(ex) {
     res.status(500).json({ msg: ex.message });
   }
});

您不會在.then返回您的承諾和價值。 categories.get()調用前添加return並在其中返回值。

如果你想在它上面使用awaitgetCategories需要返回一個 promise。 現在,它什么也沒有返回。 您需要返回您創建的承諾:

function getCategories() {
  let arr = [];
  return categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        return arr;
      });
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

請注意return關鍵字。

您也可能在這里遇到另一個問題。 您正在使用forEach迭代快照,並從傳遞給forEach的 lambda 函數中返回arr 這不會將快照數據返回給調用者。 您將需要從返回一個值, then拉姆達:

    .then(snapshot => {
      const arr = []
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
      });
      return arr;
    })

你可以嘗試這樣的事情:

function getCategories() {
  let arr = [];
  categories
    .get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log(doc.data().category);
        arr.push(doc.data().category);
        });
        console.log('arr',arr); //check the array data
        return arr;
    })
    .catch(err => {
      console.log(err);
      return [1, 2, 3];
    });
}

router.route("/categories").get(async function(req, res, next) {
  let arr = await getCategories().catch(err => {
         res.status(400).send(err);
   });
  res.json(arr);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM