Javascript: добавление в массив с результатом асинхронных c запросов - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть асинхронная c функция, которую я хочу содержать в результате трех асинхронных c запросов (это запросы пожарной базы Firebase). Я oop и пытаюсь добавить результат запросов в массив в более широкой области. К сожалению, результат массива brands всегда пуст. Это потому, что мне нужно await внутренний запрос? Есть ли лучший способ справиться с этим полностью?

async function getBrandsHelper() {
  var brands = [];
  await db
    .collection("global")
    .doc("display-data")
    .get()
    .then(doc => {
      const displayData = doc.data();
      const keys = ["p1", "p2", "p3"];
      for (const i in keys) {
        const k = keys[i];
        const product = displayData[k];
        db.collection("products")
          .doc(product)
          .get()
          .then(doc => {
            var brandData = { id: product };
            const productData = doc.data();
            brandData["image"] = productData["image"];
            brandData["title"] = productData["title"];
            brandData["description"] = productData["description"];
            brandData["url"] = productData["url"];
            brands.push(brandData);
            return;
          })
          .catch(e => {
            console.error(e);
          });
      }
      return;
    })
    .catch(e => {
      console.error(e);
    });
  return brands;
}

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

Вы должны реорганизовать свой код для использования обратных вызовов async/await или then/catch. Это не обязательно, но сделает ваш код более понятным. Думайте о них как об альтернативах для достижения того же результата: сделать асинхронный код более управляемым.

Вот как вы это сделаете с async/await (обратите внимание, что тут не задействовано then/catch):

async function getBrandsHelper() {
  let brands = [];
  try {
    // You await for the doc1 to be ready
    const doc1 = await db
      .collection("global")
      .doc("display-data")
      .get();

    const displayData = doc1.data();
    const keys = ["p1", "p2", "p3"];
    for (const i in keys) {
      const k = keys[i];
      const product = displayData[k];

      // You await for each tmpDoc before moving on
      const tmpDoc = await db.collection("products")
        .doc(product)
        .get();

      let brandData = {
        id: product
      };
      const productData = tmpDoc.data();
      brandData["image"] = productData["image"];
      brandData["title"] = productData["title"];
      brandData["description"] = productData["description"];
      brandData["url"] = productData["url"];
      brands.push(brandData);
    }

    return brands;
  } catch (error) {
    console.log(error)
    return []
  }
}

Делать это с then/catch обратными вызовами будет немного сложнее (из-за асинхронных c вызовов внутри для l oop). Вам нужно будет сохранить все Обещания в массиве, а затем использовать что-то вроде Promise.all, чтобы получить все документы для работы.

В любом случае, кажется, что вам не хватает более глубокого понимания Обещаний и асинхронности. c код в Javascript. Я предлагаю вам прочитать немного больше об Обещаниях здесь и об использовании async/await и о том, как оно относится к обещаниям здесь .

0 голосов
/ 14 апреля 2020

Вы должны использовать обещания: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise Создайте свои обещания и используйте Promise.all, чтобы сделать что-то после того, как все они будут выполнены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...