【问题标题】:Writing cleaner Promise completion closure编写更清洁的 Promise 完成关闭
【发布时间】:2018-01-12 18:10:36
【问题描述】:

Angular 和 Promise 的新手,但我意识到我已经做了很多:

this.myService.createFoo(data).subscribe(
  (result: any) => {
    resolve({success: true, data: result});
  },
  err => {
    resolve({success: false, message: err});
  });

this.myService.updateFoo(data).subscribe(
  (result: any) => {
    resolve({success: true, data: result});
  },
  err => {
    resolve({success: false, message: err});
  });

如何为我的订阅方法重写完成闭包,以免重复这样的代码?谢谢!

【问题讨论】:

  • 您可以尝试使用asyncawait,但我不确定这将是多么容易滑入您正在做的事情(不是非常熟悉角度或订阅)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • resolvereject 是如何定义的?那些来自Promise 构造函数,比如return new Promise((resolve, reject) => {...}),还是来自其他地方?如果您发布了一个更具包容性的代码示例,可能会有所帮助。
  • 是的,就像你说的普通的new promise ....

标签: angular promise subscribe


【解决方案1】:

一种方法是将您的回调提取到通用函数中并传递它们:

const successHandler = (data: any) => resolve({success: true, data });
const errorHandler = (message) => resolve({success: false, message });

this.myService.createFoo(data).subscribe(successHandler, errorHandler);
this.myService.updateFoo(data).subscribe(successHandler, errorHandler);

如果您想在 Promise 范围之外定义这些(我假设您发布的代码在其中),您可以对处理程序进行 curry:

some-util-library.js

const handlers = resolve => ({
    success: (data: any) => resolve({success: true, data }),
    error: (message) => resolve({success: false, message })
});
export { handlers };

otherfile.js

import { handlers } from './some-util-library.js';
... other code
const { success, error } = handlers(resolve);
this.myService.createFoo(data).subscribe(success, error);
this.myService.updateFoo(data).subscribe(success, error);

【讨论】:

  • 你可以像这样使用resolve,还是必须将其指定为参数?
  • 好问题,在发布的代码 OP 中 resolve 的来源并不明显,所以我认为它可以从父作用域或全局作用域获得
【解决方案2】:

我假设您正在尝试返回一个承诺,并且您发布的代码包含在一个看起来像这样的方法中:

create(): Promise<any> {
  const data = 'whatever';
  return new Promise<any>((resolve, reject) => {
    this.myService.createFoo(data).subscribe(
      (result: any) => {
        resolve({ success: true, data: result });
      },
      err => {
        resolve({ success: false, message: err });
      });
  });
}

如果是这种情况,您可以使用 toPromise 运算符将 Observable 转换为 Promise,而不是手动创建 Promise。如果您尚未导入,则需要先导入:

import 'rxjs/add/operator/toPromise';

然后,将其与asyncawait 结合,您可以将代码转换为:

async create(): Promise<any> {
  const data = 'whatever';
  try {
    const result = await this.myService.createFoo(data).toPromise();
    return { success: true, data: result }
  } catch (err) {
    return { success: false, message: err };
  }
}

【讨论】:

    【解决方案3】:

    这似乎是Angular HttpClient Interceptors 的完美用例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 2017-01-15
      • 1970-01-01
      • 2023-04-04
      • 2022-01-08
      相关资源
      最近更新 更多