回归空洞的承诺

时间:2018-03-15 14:34:57

标签: javascript angular typescript promise

我在我的应用中实现了这个button

在我的按钮组件中,我有:

  @Input() callback: () => Promise<null>;
  onClick() {
    this.spinnerService.show();
    this.callback().then(() => {
      this.spinnerService.hide();
    }, () => {
      this.spinnerService.hide();
    });
  }

(我不会使用async / await,因为&#34;技术主管&#34;也不想要我)

组件模板:

<my-button [callback]="doSomething">
</my-button>

当我将这种代码传递给组件的输入时,一切正常:

doSomething = () => {
  return myService.doSomething()
    .toPromise()
    .then((response) => console.log('promise resolved'));
}

但我需要先摆脱这个功能:

doSomething() {
  if (condition) {
    return;
  }
  return myService.doSomething()
    .toPromise()
    .then((response) => console.log('promise resolved'));
}

我得到了

  

ERROR TypeError:无法读取属性&#39;然后&#39;未定义的

我试图用相同的结果强制许诺

  if (condition) {
    return Promise.resolve(null);
    // or
    return new Promise((resolve) => { resolve(null); });
  }

2 个答案:

答案 0 :(得分:3)

对于此输入

@Input() callback: () => Promise<null>;

无法保证将其分配给适当的值。额外检查是否应添加指定callback

更安全的方法是在这些地方使用async函数,因为它们始终使用承诺:

  async onClick() {
    this.spinnerService.show();

    try {
      if (this.callback)
        await this.callback()
    } finally {
      this.spinnerService.hide();
    }
  }

doSomething应该无条件地返回一个承诺,这也可以通过async解决:

async doSomething() {
  if (!condition)
    return myService.doSomething().toPromise();
}

如果由于某种原因无法使用async函数(虽然没有好的,因为它们是规范兼容的,TypeScript中的一等公民),应该在函数中一致地处理promises(也有助于测试)。 doSomething未正确输入,这会导致函数返回不正确。它应该是:

  onClick(): Promise<void> {
    this.spinnerService.show();

    return Promise.resolve(this.callback ? this.callback() : undefined)
    .catch(() => {})
    .then(() => {
      this.spinnerService.hide();
    });
  }

doSomething(): Promise<void> {
  if (condition) {
    return Promise.resolve();
  }

  return myService.doSomething().toPromise();
}

callback的类型为Promise<void>,而不是Promise<null>

常规(非箭头)doSomething方法应绑定到构造函数中的this

答案 1 :(得分:1)

试试这个

doSomething() {
  if (condition) {
    return new Promise((resolve,reject)=> reject('Some Error Message'));
  }
  return myService.doSomething()
    .toPromise()
    .then((response) => console.log('promise resolved'));
}