猿问

如何在从我的承诺/函数返回之前等待 forEach 完成

我有一个角度函数来从一个 firestore 集合中获取产品,然后循环该查询的结果以从另一个集合中查找价格。


我怎样才能等到 forEach 的价格完成后再从外部承诺和外部函数本身返回?


返回的结果包含一个产品数组,但每个产品的价格数组为空。


 const products = await this.billingService.getProducts();

async getProducts() {

    let result = [];

    let product = {};

    return this.db.collection(

      'products',

      ref => { ref

        let query: Query = ref;

          return query.where('active', '==', true)

      })

      .ref

      .get()

      .then(function (querySnapshot) {

        querySnapshot.forEach(async function (doc) {

          product = doc.data();

          product['prices'] = [];


          await doc.ref

            .collection('prices')

            .orderBy('unit_amount')

            .get()

            .then(function (docs) {

              // Prices dropdown

              docs.forEach(function (doc) {

                const priceId = doc.id;

                const priceData = doc.data();

                product['prices'].push(priceData);

              });

            });

        });

        result.push(product);

        return result;

      });

  }

我也尝试过这种方法,但不知道如何访问结果


await this.billingService.getProducts().then(results =>

getProducts() {

      const dbRef =

        this.db.collection(

          'products',

          ref => { ref

            let query: Query = ref; return query.where('active', '==', true)

        });

       const dbPromise = dbRef.ref.get();


      return dbPromise

        .then(function(querySnapshot) {

          let results = [];

          let product = {};

          querySnapshot.forEach(function(doc) {

            let docRef = doc.ref

              .collection('prices')

              .orderBy('unit_amount')

              results.push(docRef.get())

          });

          return Promise.all(results)

        })

        .catch(function(error) {

            console.log("Error getting documents: ", error);

        });

    } 


暮色呼如
浏览 128回答 3
3回答

函数式编程

根据评论发布为社区 Wiki 答案。对于这种情况,使用 aforEach()不是正确的选择。正如此处所澄清的那样,无法forEach()与await函数正常工作,这样,就无法与您的承诺正常工作。考虑到这一点以及您想要按顺序读取数据的事实 - 因为一个查询的结果将影响第二个查询 - 您需要使用普通 , 来循环for数据和数组。

不负相思意

让 getProducts() 函数成为一个承诺。因此,只有当您解决它(或拒绝它)时它才会返回。getProducts() {return new Promise((resolve,reject)=> {let result = [];let product = {};this.db.collection(  'products',  ref => { ref    let query: Query = ref;      return query.where('active', '==', true)  })  .ref  .get()  .then(function (querySnapshot) {    querySnapshot.forEach(async function (doc) {      product = doc.data();      product['prices'] = [];      doc.ref        .collection('prices')        .orderBy('unit_amount')        .get()        .then(function (docs) {          // Prices dropdown          docs.forEach(function (doc) {            const priceId = doc.id;            const priceData = doc.data();            product['prices'].push(priceData);          });          resolve(result);// returns when it reaches here        });    });    result.push(product);  }); })}然后你可以使用 then 或await 来调用promisethis.billingService.getProducts().then( res => { const products = res;})使用等待const products = await this.billingService.getProducts();

守着一只汪

此版本的代码有效:&nbsp; getProducts(): Promise<any> {&nbsp; &nbsp; return new Promise((resolve,reject)=> {&nbsp; &nbsp; &nbsp; let result = [];&nbsp; &nbsp; &nbsp; let product = {};&nbsp; &nbsp; &nbsp; this.db.collection(&nbsp; &nbsp; &nbsp; &nbsp; 'products',&nbsp; &nbsp; &nbsp; &nbsp; ref => { ref&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let query: Query = ref;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return query.where('active', '==', true)&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; .ref&nbsp; &nbsp; &nbsp; &nbsp; .get()&nbsp; &nbsp; &nbsp; &nbsp; .then(async function (querySnapshot:firebase.firestore.QuerySnapshot) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(const doc of querySnapshot.docs) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const priceSnap = await doc.ref&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collection('prices')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .orderBy('unit_amount')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .get()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; product = doc.data();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; product['prices'] = [];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Prices dropdown&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(const doc of priceSnap.docs) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const priceId = doc.id;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let priceData = doc.data();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; priceData['price_id'] = priceId;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; product['prices'].push(priceData);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resolve(result);// returns when it reaches here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result.push(product);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; })&nbsp; }
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答