如何在 Q 和 TypeScript 中将链的承诺转换为平面承诺

How transform chain's promises into flat promise in Q and TypeScript

我想知道是否有办法将 chain 的 promise 转换为 flat promise。我有这个代码:

import * as Q from 'q';
export class MyClass {

  private methodA(): Q.Promise<boolean> {
    let deferred = Q.defer<boolean>();
    //some stuff, like database calls, etc
    return deferred.promise;
  }

  private methodB(): Q.Promise<boolean> {
    let deferred = Q.defer<boolean>();
    //some stuff, like database calls, etc
    return deferred.promise;
  }

  private methodC(): Q.Promise<boolean> {
    let deferred = Q.defer<boolean>();
    //some stuff, like database calls, etc
    return deferred.promise;
  }

  private methodD(): Q.Promise<boolean> {
    let deferred = Q.defer<boolean>();
    //some stuff, like database calls, etc
    return deferred.promise;
  }

  run(): Q.Promise<boolean> {
    let deferred = Q.defer<boolean>();
    let promises = [];

    promises.push(this.methodA().then(wasOk => {
      this.methodB().then(wasOk => {
        this.methodC();
      });
    }));

    promises.push(this.methodD());

    //Wait all promises
    Q.all(promises).then(wasOk => deferred.resolve(wasOk));

    return deferred.promise;
  }
}

这段代码有一个问题:Q.all只有在等待methodA和methodD;并且不等待 methodB 和 methodC。

我想我需要将方法 B 和 C 放在 promises 的向量中,或者甚至制作另一个向量并先在里面等待它 Q.all...但这不是一个清晰的代码,我想知道有没有更好的方法。

非常感谢!

你有一个小错误,几乎是错字:

promises.push(this.methodA().then(wasOk => {
      this.methodB().then(wasOk => {
        this.methodC();
      });
    }));

是大括号——它们将承诺的 return 更改为未定义的 return。你可以这样做:

promises.push(this.methodA().then(wasOk => 
      this.methodB().then(wasOk => 
        this.methodC();
      );
    ));

或者这个:

promises.push(this.methodA().then(wasOk => {
      return this.methodB().then(wasOk => {
        return this.methodC();
      });
    }));

甚至这样:

promises = [this.methodA(), this.methodB(), this.methodC()];

您只是在 methodA 上的 then 处理程序中缺少 return,并且可能在其 then 处理程序中,因为您正在使用 详细箭头函数:

promises.push(this.methodA().then(wasOk => {
  return this.methodB().then(wasOk => {
//^^^^^^^
    return this.methodC();
//  ^^^^^^^
  });
}));

或者使用简洁箭头函数:

promises.push(this.methodA().then(wasOk => this.methodB().then(wasOk => this.methodC())));

或带有换行符的简洁箭头:

promises.push(this.methodA().then(wasOk =>
  this.methodB().then(wasOk =>
    this.methodC()
  )
));

请注意,该代码执行此操作:

  • 调用methodA并等待它解决,然后
  • 调用methodB并等待它解决,然后
  • 通话次数methodC

总的来说,数组中的第一个承诺在 methodBmethodC 解析之前不会解析; methodD 被立即调用,因此可以更快地解决。

数组构造也可以更简单:

promises = [
  this.methodA().then(wasOk =>
    this.methodB().then(wasOk =>
      this.methodC()
    )
  ),
  this.methodD()
];