【问题标题】:Returning empty promise返回空头承诺
【发布时间】:2018-08-24 10:16:46
【问题描述】:

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

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

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

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

组件模板:

<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: Cannot read property 'then' of undefined

我试过强制一个具有相同结果的承诺

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

【问题讨论】:

  • 哪个“then”属性导致问题?
  • @Sharcoux,然后来自按钮组件。第一个代码块
  • (I don't use async / await because the "tech lead" doesn't want me too) StackOverflow 无法帮助您解决公司间的自负 ;)
  • Promise 不是这里的问题。您正在关注位于受控代码之前的 if(condition)。
  • 多么奇怪。我尝试了类似的方法,并且效果很好。您是否尝试检查满足条件时 doSomething() 方法真正返回的内容?我的意思是,你没有任何破坏 Promise.resolve 的库,不是吗?你能做到这一点,看看它返回什么? console.log(this.callback()) 在你的 onClick() 方法中

标签: javascript angular typescript promise


【解决方案1】:

对于这个输入

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

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

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

  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 中的一等公民),promise 应该在函数中一致地处理(也有助于测试)。 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&lt;void&gt;,而不是Promise&lt;null&gt;

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

【讨论】:

  • 很棒的解释,很高兴看到 async/await 与经典 Promise 的比较。你让我头疼不已。
【解决方案2】:

试试这个

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

【讨论】:

  • 你在哪里调用这个函数?
  • 它作为输入传递给按钮组件(第一个代码块),我刚刚编辑了它的初始化方式
  • @gyc 这是您代码中唯一在未定义时访问.then 的地方。如果此答案对您不起作用,则由于某种原因未应用代码更改,或者存在您未显示的其他问题。
猜你喜欢
  • 2019-07-16
  • 2015-11-04
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
  • 2014-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多