返回空头承诺

gyc*_*gyc 6 javascript promise typescript angular

我正在我的应用程序中实现这个按钮

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

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

(我不使用 async / await 因为“技术负责人”也不想要我)

组件模板:

<my-button [callback]="doSomething">
</my-button>
Run Code Online (Sandbox Code Playgroud)

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

doSomething = () => {
  return myService.doSomething()
    .toPromise()
    .then((response) => console.log('promise resolved'));
}
Run Code Online (Sandbox Code Playgroud)

但我需要更早地打破这个功能:

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

我得到

错误类型错误:无法读取未定义的属性“then”

我试过用相同的结果强制承诺

  if (condition) {
    return Promise.resolve(null);
    // or
    return new Promise((resolve) => { resolve(null); });
  }
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 6

对于这个输入

@Input() callback: () => Promise<null>;
Run Code Online (Sandbox Code Playgroud)

不能保证它被分配到正确的值。callback应该添加额外的检查是否指定。

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

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

    try {
      if (this.callback)
        await this.callback()
    } finally {
      this.spinnerService.hide();
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

async doSomething() {
  if (!condition)
    return myService.doSomething().toPromise();
}
Run Code Online (Sandbox Code Playgroud)

如果async由于某种原因不能使用函数(虽然没有好的函数,因为它们是符合规范的,TypeScript 中的一等公民),则应在函数中始终如一地处理 Promise(也有助于测试)。doSomething类型不正确,这会导致不正确的函数返回。它应该是:

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

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

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

  return myService.doSomething().toPromise();
}
Run Code Online (Sandbox Code Playgroud)

callbackwill的类型是Promise<void>,不是Promise<null>

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