为什么我需要输入两次这个命令才能在Typescript,Ionic 2中工作?

时间:2017-03-25 23:41:15

标签: javascript typescript ionic-framework ionic2

我一直在寻找2个小时的问题,我的回调函数不会忽略Ionic 2中的LoadingController。

我有一个函数hideLoading():

hideLoading()
{
    this.loader.dismiss();
}

在成功函数中调用

connectionSuccess = () =>
{
    this.hideLoading();

    var toast = Toast.create({
        message: '...',
        duration: 3000});

    this.nav.present(toast);
}

由于某种原因它不起作用..但我发现它有效 - 如果我在其间放置一个警报();或者如果我将代码更改为:

connectionSuccess = () =>
{
    this.hideLoading();
    this.loader.dismiss();
    [...] 
}

是否与时间有关?警报()之间的时间或第二个隐藏指令似乎解决了它..我在解雇之前检查了控制台日志中this.loader的内容,这是完全正确的。

如果我删除上述两条指令中的一条,则无效。它需要两个指令 - 基本上做同样的事情,但只能一起工作..?

这是一个非常脏的修复。我怎么能以干净的方式解决这个问题?我不明白为什么它的行为如此不可预测。

1 个答案:

答案 0 :(得分:1)

根据在评论中进行的讨论,我们知道this.Loader是一个离子角度Loading类的实例,并且它的dismiss方法返回,至少在在OP的上下文中运行ZoneAwarePromise实例。

ZoneAwarePromise是为 zone.js 创建的专用Promise实现,Angular依赖该库来破坏DOM并重新连接编排异步回调和事件,但我离题......

重点是它基本上是Promise,并且明确表示异步 API。我们需要适当地与这样的API交谈,因为在火灾和忘记方式中使用它会导致时间问题,例如OP中指示的行为。

下面我将根据OP的代码说明我认为的正确重写代码。

  1. 在TypeScript> = 2.2.0和ES2017中,我们可以利用两种方法来干净利落地正确处理基于承诺的API,并确保相关逻辑的正确执行顺序。

    async / await。这可以被认为是与基于Promise的API进行交互的首选方式,因为它提供了出色的可读性并允许标准的异常处理模型。写作也非常简洁和愉快。

    export default class {
    
      async hideLoading() {
        // note we probably don't need the try wrapper
        // it is good practice to NOT handle unknown errors
        // just put it here for illustrative purposes
        try {
          await this.loader.dismiss();
        } 
        catch (e) {
          console.error(e);
        }
      }
    
      connectionSuccess = async () => {
        await this.hideLoading();
    
        const toast = Toast.create({
          message: '...',
          duration: 3000
        });
    
        this.nav.present(toast);
      };
    
    }
    
  2. 在旧版本的TypeScript中,async / await仅支持--target es2015。如果我们需要定位es5并且有一个我们无法升级的旧版TypeScript(你真的应该尽可能升级),那么我们可以用以下方式用相同的语义编写上面的代码

    export default class {
    
      hideLoading() {
        // note we probably don't need the .catch call
        // it is good practice to NOT handle unknown errors
        // just put it here for illustrative purposes
        return this.loader.dismiss()
          .catch(e => console.error(e));
      }
    
      connectionSuccess = () => {
        this.hideLoading()
          .then(() => {
            const toast = Toast.create({
              message: '...',
              duration: 3000
            });
    
            this.nav.present(toast);
          });
      };
    
    }
    
  3. 这里的关键是当我们谈论异步API时,我们必须使用异步编程模型。如果API是基于Promise的,就像这里的那个,那么通过async / await使用它几乎是毫不费力的改变,因为我们甚至可以保留顺序异常处理机制。

    如果我们的转换器或运行时没有async / await支持,我们可以使用Promise.prototype.thenPromise.prototype.catch来完成相同的目标来编写代码以最小的麻烦完成工作。

    如果API基于Observable,那么我们需要更复杂的转换,并且不能选择使用async / await等语法糖。 1功能

    注意:

    1. 在RxJS'原始语言,C#和Visual Basic,async / await LINQ理解都可直接在Observable上作为句法糖进行操作。它们可能不是最合适的,但这可能会有所帮助。在JavaScript中,我们没有这样的设施。