Внутри обещания я хочу присвоить значение (само значение происходит из другого обещания) переменной, которая будет использоваться вне этого обещания - PullRequest
2 голосов
/ 29 июня 2019

В моей базе данных Firestore у меня есть две коллекции books и categories.В коллекции категорий все документы имеют только одно поле, т.е. name, а в коллекции books документ содержит несколько полей, и одно из них - type, которое представляет собой массив типа данных DocumentRef, что означает, что каждый документ в книгах можетиметь несколько значений категорий-имен.

Теперь для каждого документа в коллекции books я хочу получить все значения имен связанных категорий в одной строке.

Это то, что у меня есть до сих пор.

database
    .collection("books")
    .get()
    .then(snapshot => {
        snapshot.forEach(doc => {
            renderTypes(doc);
        });
    });

/** The renderTypes function **/
renderTypes = doc => {
    let typeArrayRef = doc.data().type; // assigning the array of documentRefs

    console.log("total elements in types array is ", typeArrayRef.length);
    promiseVar = new Promise((resolve, reject) => {
        typeList = " ";
        // looping through each items inside the array
        typeArrayRef.forEach(type => {
            type.get().then(res => {
                typeList = typeList + " " + res.data().name;
            });
            // unccommenting this line gives a mixed output (out of order)
            // console.log(`String containing all the types are ${ type }`);
        });
        resolve(type); // resolving with type string
    });

    promiseVar.then(type => {
        console.log("Inside the then of promiseVar", type);
    });
};

Теперь я получаю вывод:

total elements in types array is 6 
total elements in types array is 3
total elements in types array is 1 

Inside the then of promiseVar
Inside the then of promiseVar 
Inside the then of promiseVar

В последних трех строках ничего не печатается, кроме регистрациион внутри promiseVar дает вывод, но смешан (т. е. нет фиксированного порядка).

Кажется, что promiseVar разрешается сразу.Есть ли способ обойти это?

1 Ответ

4 голосов
/ 29 июня 2019

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

renderTypes = doc => {
    const typeArrayRef = doc.data().type; // assigning the array of documentRefs
    console.log("total elements in types array is ", typeArrayRef.length);

    const promiseVar = Promise
      .all(typeArrayRef.map(type => type.get()))
      .then(types => {
        const typeList = types.map(type => type.data().name).join(' ');
        return typeList;
      });

    promiseVar.then(type => {
        console.log("Inside the then of promiseVar", type);
    });
};

Сначала мы создаем список обещаний и ожидаем их выполнения. Когда все будет готово, types - это список всех ответов. Цепочка .then заставляет promiseVar разрешить желаемый результат. Мы можем сделать это еще проще с помощью ключевого слова await:

renderTypes = async doc => {
    const typeArrayRef = doc.data().type; // assigning the array of documentRefs
    console.log("total elements in types array is ", typeArrayRef.length);

    const types = await Promise.all(typeArrayRef.map(type => type.get()));
    const typeList = types.map(type => type.data().name).join(' ');

    // Not really _inside_ now.
    console.log("Inside the then of promiseVar", typeList);
};
...