【问题标题】:How do I return the value of a promise inside another promise?如何在另一个 Promise 中返回一个 Promise 的值?
【发布时间】:2019-09-17 00:09:08
【问题描述】:

我试图在一个 promise 中返回一个 promise 函数的值。仍然很新的承诺,所以任何建议都非常感谢!

// card.service.ts

getCard(cardId: string): DocumentData {
    return firebase.firestore().collection('users').doc(this.currentUserId)
        .collection('cardsList').doc(cardId)
        .get()
        .then((docSnapShot) => {
            console.log((docSnapShot));
            return docSnapShot.data();
        },
        (err) => {
            console.log(err);
        });
  }

addCardToWallet(userId: string, cardId: string, dataObject: DocumentData) {
      return firebase.firestore().collection('users').doc(userId)
          .collection('walletList')
          .doc(cardId)
          .set(
              dataObject
          );
  }

// scanner.component.ts
scanCode() {
   this.barcodeScanner.scan(
          {
           showFlipCameraButton : true, // iOS and Android
           showTorchButton : true, // iOS and Android
           prompt : 'Scan a Kardbox QR' // Android
          }
     ).then((barcodeData) => {
         this.cardService.getCard(barcodeData.text)
             .then((data) => {
               // I want to add this to the database first

               this.cardService.addCardToWallet(this.currentUserId, barcodeData.text, data);

              // After adding values to database, navigate to other page

              this.router.navigate(['/home/wallet']);
        });
     });
 }

我得到的输出是barcodeData 的值,我不知道为什么会这样。

【问题讨论】:

  • 我得到的输出是什么意思?该输出在调用scanCode() 方法的方法中?
  • 是的,你是对的!
  • 你想从scanCode()返回什么结果?

标签: angular typescript firebase google-cloud-firestore ionic4


【解决方案1】:

我认为你应该尝试异步等待,替换:

this.barcodeScanner.scan(
        {
          showFlipCameraButton : true, // iOS and Android
          showTorchButton : true, // iOS and Android
          prompt : 'Scan a Kardbox QR' // Android
        }
    ).then((barcodeData) => {
        this.cardService.getCard(barcodeData.text)
            .then((data) => {
              // I want to add this to the database first
          this.cardService.addCardToWallet(this.currentUserId, barcodeData.text, data);

          // After adding values to database, navigate to other page

          this.router.navigate(['/home/wallet']);
    });
});

与:

const barcodeData = await this.barcodeScanner.scan(
  {
    showFlipCameraButton : true, // iOS and Android
    showTorchButton : true, // iOS and Android
    prompt : 'Scan a Kardbox QR' // Android
  },
);
const data = await this.cardService.getCard(barcodeData.text);

this.cardService.addCardToWallet(this.currentUserId, barcodeData.text, data);
this.router.navigate(['/home/wallet']);

并且不要忘记在 scancode() 方法之前添加异步。

【讨论】:

  • 您好,Msu Arven。谢谢你的回答。我测试了您的解决方案,但不幸的是,它没有用。没有任何东西被添加到数据库中,我也没有被重定向到另一个页面。
  • 添加try catch和控制台记录错误看看是什么问题
  • 表示 this.cardService.getCard 承诺中的“数据”未定义
  • 嗯,如果你在 try catch 块中初始化你的 const,那么 const 不能在这个 try catch 范围之外使用,所以把 addCardToWallet 和 navigate 方法放在 try catch 中
【解决方案2】:

您应该在 getCard(cardId: string) 函数中返回一个承诺

getCard(cardId: string): Promise<DataType or any> {
    const promise = new Promise((resolve,reject) => { 
         firebase.firestore().collection('users').doc(this.currentUserId)
        .collection('cardsList').doc(cardId)
        .get()
        .then((docSnapShot) => {
            console.log((docSnapShot));
            resolve(docSnapShot.data());
        },
        (err) => {
            console.log(err);
        });
    });
    return promise;
  }

如果要在数据添加到数据库后进行导航,则应将 router.navigate 放入 addCardToWallet 方法的回调中

this.cardService.addCardToWallet(this.currentUserId, barcodeData.text,data).then(res => {
      router.navigate(/somwhere)
});

【讨论】:

  • 嗨 Ranika,非常感谢您的回答。不幸的是,我也遇到了与下面提供的其他解决方案相同的错误
【解决方案3】:

也许这会有所帮助。如果没有请告诉我。

scanCode( ) {
    this.barcodeScanner.scan({
        showFlipCameraButton: true,
        showTorchButton: true,
        prompt: 'Scan a Kardbox QR'
    })
    .then( ( barcodeData ) => {
        this.cardService.getCard( barcodeData.text )
            .then( ( data ) => {
               // addCardToWallet returns a promise, right? Wait for it to return
               this.cardService.addCardToWallet( this.currentUserId, barcodeData.text, data )
                   .then( ( ) => {
                       // And after the card is added, tell the router to navigate
                       this.router.navigate([ '/home/wallet' ]);
                   })
            });
     })
     // Just in case, I recommend you to catch any error that might arise in the promise chain
     .catch( ( error ) => {
         console.error( 'Oops, something failed: "' + error + '"' );
     });
 }

【讨论】:

  • 感谢您回答帕托。错误是说 this.cardService.getCard 承诺中的“数据”未定义。你能告诉我吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 2020-08-06
  • 2017-06-18
相关资源
最近更新 更多