为什么点击两次后得到值? + 承诺

Why getting the value after clicking it twice? + Promise

我在处理 angular 中的 promise 函数时缺乏对异步操作的理解。所以基本上,我试图从 promise 方法中获取一个值并将其分配给组件中的全局变量。但是,当我点击一个按钮时,我无法检索到该值,当我再次点击一个按钮后,它终于开始显示该值。

单击它时出现错误一次:

Cannot read property 'matchId' of undefined

点击两次得到的值:

3

Html:

<button type="submit" (click)="loadInfo(form)">Submit</button>

服务:

@Injectable()
export class Web3Service {
    constructor...

    getInfo(address: string): Promise<any> {
        return this.TestBetting.deployed().then((instance) => {
          return instance.getInfo.call(address);
        })
        .then((value) => {
          var serialized = this.itemsService.getSerialized<IGetInfo>(value); 
          return this.mappingService.mapValueToGetInfo(serialized); 
        })
        .catch((e) => {
          console.log(e);
        });
    }  
}

组件:

export class HomeComponent {
    infoMapped: any;

    constructor(private web3Service: Web3Service) {}

    loadInfo(): void {
        var test = this.web3Service.getInfo(this.address); 
        test.then((value) => {
            this.infoMapped = value;
        })

        // this.infoMapped.matchId is undefined on a first attempt
        var length = this.infoMapped.matchId;
        for (var i = 0; i < length; i++) {
        //...
        }
    }
}

需要修复什么才能在单击按钮一次后检索 infoMapped 值?

问题仍然是 test.then() 之后的代码(即 for)将在 之前执行this.infoMapped = value; 因为 this.infoMapped = value; 只会在 test 承诺解决时执行,并且它只会在 for 运行后的某个时间解决.

我的建议是:将 "handling" 逻辑移动到一个新方法并从 .then().

中调用它

所以,这个:

loadInfo(): void {
    var test = this.web3Service.getInfo(this.address); 
    test.then((value) => {
        this.infoMapped = value;
    })

    // this.infoMapped.matchId is undefined on a first attempt
    var length = this.infoMapped.matchId;
    for (var i = 0; i < length; i++) {
    //...
    }
}

会变成这样:

loadInfo(): void {
    var test = this.web3Service.getInfo(this.address); 
    test.then((value) => {                 // <=== changed this line
        this.handleInfo(value)             // <=== changed this line
     });
}

handleInfo(value): void {                   // <=== added this whole method.
    this.infoMapped = value;

    var length = this.infoMapped.matchId;
    for (var i = 0; i < length; i++) {
    //...
    }
}