【问题标题】:Wait until async call has finished - Ionic2等到异步调用完成 - Ionic2
【发布时间】:2017-01-22 16:31:23
【问题描述】:

我在 Ionic2 工作,我遇到了这个问题: 在我的组件中有 drawPlayer 方法,它从 firebase 数据库中检索数据。

这是它的代码:

drawPlayer(){
    this.playerData.drawThePlayer().on('value', snapshot => {
      // some stuff
    });
    return this.drawnPlayer;   // returns the player name
}

ngOnInit 函数内的同一个文件(组件)中,我需要调用 drawPlayer() 并且我这样做:

ngOnInit(){
let myVar = this.drawPlayer();
console.log("test: "+myVar);
}

如果我检查我阅读的控制台test: undefined,如果我返回并再次返回该页面,我会看到test: a correct value。我认为这是因为 drawPlayer() 是一个异步调用,而当我执行 console.log 时,它还没有返回结果。

那么,我怎样才能在drawPlayer() 完成后才console.log

/**************************************************** *******************************/

编辑:(在 httpNick 回答之后)

现在我有了这个带有完整代码的drawPlayer() 方法(this.drawnPlayer 是从这些方法中全局定义的):

drawPlayer(cb){
    this.playerData.drawThePlayer().on('value', snapshot => {
      var data = snapshot.val();
      for (var key in data){
            this.drawnPlayer = String(data[key].lastName);
            console.log("playerName: "+this.drawnPlayer);
      }
    });
    console.log("test: "+this.drawnPlayer);
    cb(this.drawnPlayer);   // returns the player name
}

ngOnInit() 是这样的:

this.drawPlayer(function(valueFromDrawPlayer) {
    console.log("callback result: "+valueFromDrawPlayer);
});
console.log("after the callback");

当我运行应用程序时,这是我在浏览器控制台中看到的:

test: undefined
callback result: undefined
after the callback
EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property '0' of undefined
playerName: John

但我希望读到这个:

playerName: John
test: John
callback result: John
after the callback

【问题讨论】:

    标签: javascript angular typescript ionic2


    【解决方案1】:

    我不确定this.drawnPlayer 的来源,但如果您将回调函数传递给drawPlayer,您可以在异步代码运行完成后调用它以记录返回值。

    drawPlayer(cb){
        this.playerData.drawThePlayer().on('value', snapshot => {
          // some stuff
        });
        cb(this.drawnPlayer);   // returns the player name
    }
    ngOnInit(){
        drawPlayer((x) => { console.log(x) });
    }
    

    最后一行也可以改写成这样:

    drawPlayer(function(valueFromDrawPlayer) {
        console.log(valueFromDrawPlayer);
    });
    

    查看完整代码后进行编辑:

    drawPlayer(cb){
        this.playerData.drawThePlayer().on('value', snapshot => {
          var data = snapshot.val();
          for (var key in data){
                this.drawnPlayer = String(data[key].lastName);
                console.log("playerName: "+this.drawnPlayer);
                cb(this.drawnPlayer);   // returns the player name
          }
        });
    }
    

    【讨论】:

    • 你能解释一下最后一行:drawPlayer((x) => { console.log(x) });什么是“x”?
    • 我更新了我的答案以显示它可以重写为什么。基本上 x 是我将传递给drawPlayer 的匿名回调函数的命名不佳的参数。所以在上述情况下,cb(this.drawnPlayer); 会将this.drawnPlayer 作为x 传递给函数。如果您想了解更多关于我用于该行的语法,它是arrow function
    • 谢谢。我应该把“最后一行”放在 ngOnInit 方法中吗?对不起,如果这个问题看起来很愚蠢。我会尽快深入研究回调
    • 我已经按照你说的做了,但还是有问题。我已经用我得到的结果/错误编辑了问题
    • 查看您现在发布的完整代码,您需要在.on('value', snapshot => { } 回调函数中调用回调,以便确保已设置 this.drawnPlayer。这就是您的 console.log("playerName: "+this.drawnPlayer); 显示未定义值的原因。查看我的更新答案
    【解决方案2】:

    尝试围绕异步调用创建一个同步包装器。通常,您不想这样做,因为它会阻塞整个线程池。如果必须使用等待来阻止异步返回方法。它基本上违背了首先使用异步的目的。

       public static whatever CallAndWaitAsync()
       {
           task.Wait(); // Block thread until completed
           var result = task.Result;
           return result;
       }
    

    【讨论】:

      猜你喜欢
      • 2019-05-31
      • 2016-02-03
      • 2021-01-30
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2019-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多