简体   繁体   中英

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

I want to know if there is a way to transform chain's promises in a flat promise. I have this code:

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;
  }
}

This code have one problem: Q.all only is waiting to methodA and methodD; and is not waiting for methodB and methodC.

I think I will need to put method B and C in promises's vector, or even make another vector and wait for it inside first Q.all... but it will be not a clear code, and I wondering if there a better aproach.

Thanks a lot!

You're just missing a return in your then handler on methodA , and probably within its then handler, because you're using verbose arrow functions:

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

Or with concise arrow functions:

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

Or with concise arrows with line breaks:

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

Note that that code does this:

  • Calls methodA and waits for it to resolve, then
  • Calls methodB and waits for it to resolve, then
  • Calls methodC

So overall, the first promise in your array won't resolve until methodB and methodC resolve; methodD is called right away and so could resolve sooner.

The array construction could be simpler as well:

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

You have a slight error, almost a typo:

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

It's the curly braces -- they change a return of a promise into a return of undefined. You could do this:

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

or this:

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

or even this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM