Как сделать так, чтобы функция экспресс-вызова приложения ожидала перед вызовом res.send без использования setTimeout ()? - PullRequest
1 голос
/ 27 сентября 2019

Я бы хотел, чтобы моя функция обратного вызова подождала, пока ClientProductLinks не будет заполнено, прежде чем отправить ее через res.send ().Я уверен, что есть простое решение, но я новичок в JS и не могу понять это.

app.all('/:client/listproducts', async function(req, res) {
   const client = req.params.client;
   let clientProductLinks = [];
   const clientRef = await db.collection(client).get();
   const snapshot1 = await clientRef;
   snapshot1.forEach(async function (prod) {
       let prodRef = await db.collection(client).doc(prod.id).collection(prod.id).get();
       let snapshot2 = await prodRef;
       snapshot2.forEach(function (doc) {
           const obj = {
               docID: doc.id,
               docData: doc.data()
           };
           clientProductLinks.push(obj);
       });
   });
   res.send(clientProductLinks);
});

В настоящее время res.send () отправляет ClientProductLinks обратно как пустой массив.Любая помощь с благодарностью.

1 Ответ

2 голосов
/ 27 сентября 2019

Вы ожидаете синхронного выполнения (snapshot1.forEach), когда действительно пишете асинхронный код.

В этом случае вы сможете использовать Promise.all для ожидания всех ссылок на ваш продукт.

Что-то вроде (не проверено):

app.all('/:client/listproducts', async function(req, res) {
  const client = req.params.client;
  const snapshot1 = await db.collection(client).get();
  const getProduct = async prod => {
    return new Promise(async (resolve, reject) => {
      try {
        const snapshot2 = await db
          .collection(client)
          .doc(prod.id)
          .collection(prod.id)
          .get();
        const links = [];
        snapshot2.forEach(function(doc) {
          const obj = {
            docID: doc.id,
            docData: doc.data()
          };
          links.push(obj);
        });
        resolve(links);
      } catch (error) {
        reject(error);
      }
    });
  };

  const clientProductLinks = await Promise.all(snapshot1.map(getProduct));
  res.send(clientProductLinks);
});
...