简体   繁体   English

如何等待Javascript ECMAScript2015(ES6)中的整个承诺链完成

[英]How to wait on completion of a whole chain of Promises in Javascript ECMAScript2015 (es6)

Pretty new to es6 and curious to know whether now with Promises, I can do away with future.wait() es6的新手,好奇地知道现在是否可以使用Promises,我可以取消future.wait()

I have a method called execute() , which starts a chain of promises. 我有一个称为execute()的方法,该方法启动了承诺链。 I have two requirements of this method: 我对此方法有两个要求:

  • Each promise should only start when the last promise has completed (this part I have achieved) 每个承诺只能在最后一个承诺完成时开始(我已经实现的这一部分)
  • execute() should only return when the whole chain of promises has completed executing (ie I want to block until the last promise is complete) execute()仅应在整个promise链完成执行后返回(即,我想阻塞直到最后一个promise完成)

Here is my sample code: 这是我的示例代码:

/* Require dependencies */
require('babel/polyfill');

class PromiseWaiter {
  /* Constructor */
  constructor() {
  }

  /* Methods */
  execute() {
    let _this = this;

    runPromiseGenerator(function *promiseGenerator() {
      yield _this.asyncMethod1();
      yield _this.asyncMethod2();
      yield _this.asyncMethod3();
    });

    return true;
  }

  asyncMethod1() {
    return returnDummyPromise('method 1', 800);
  }
  asyncMethod2() {
    return returnDummyPromise('method 2', 200);
  }
  asyncMethod3() {
    return returnDummyPromise('method 3', 200);
  }
}

var runPromiseGenerator = function(generator) {
  var it = generator(), ret;

  // asynchronously iterate over generator
  (function iterate(val) {
    ret = it.next(val);

    if (!ret.done) {
      // poor man's "is it a promise?" test
      if ("then" in ret.value) {
        // wait on the promise
        ret.value.then(iterate);
      }
      // immediate value: just send right back in
      else {
        // avoid synchronous recursion
        setTimeout( function(){
          iterate(ret.value);
        }, 0);
      }
    }
  })();

};

var returnDummyPromise = function(methodName, timeout) {
  console.log('starting %s', methodName);
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log('finished %s', methodName);
      resolve();
    }, timeout);
  })
};

module.exports = PromiseWaiter;

Here is what I run on the node console to test & the current output: 这是我在节点控制台上运行以测试和当前输出的内容:

> p = new PromiseWaiter()
{}
> p.execute()
starting method 1
true
> finished method 1
starting method 2
finished method 2
starting method 3
finished method 3

What I want to see is: 我想看的是:

> p = new PromiseWaiter()
{}
> p.execute()
starting method 1
finished method 1
starting method 2
finished method 2
starting method 3
finished method 3
true
>

In the past I would have done this using 过去我会使用

fut = new Future();
// set off chain passing future
future.wait();

Wanted to pick the brains of the best and brightest out there. 想要从那里挑选最好,最聪明的大脑。

Thanks in advance for your time! 在此先感谢您的时间! Elliott 埃利奥特

You'll need to return a promise that will resolve when the generator has completed. 您需要返回一个承诺,该承诺将在生成器完成后解决。 I'd really recommend using an existing implementation like co however if you wanted to expand your own implementation: 我真的建议使用像co这样的现有实现,但是如果您想扩展自己的实现:

var runPromiseGenerator = function(generator) {
  return new Promise(function(resolve, reject){
    var it = generator(), ret;

    // asynchronously iterate over generator
    (function iterate(val) {
      try {
        ret = it.next(val);

        if (!ret.done) {
          Promise.resolve(ret.value).then(iterate, reject);
        }
        else {
          resolve(ret.value);
        }
      }
      catch (e){
        reject(e);
      }
    })();
  });
};

then you can alter your execute to be 然后您可以将您的execute更改为

execute() {
  let _this = this;

  return runPromiseGenerator(function *promiseGenerator() {
    yield _this.asyncMethod1();
    yield _this.asyncMethod2();
    yield _this.asyncMethod3();
  });
}

and do 并做

p.execute().then(function(){
  // done
});

Alternatively, you can use your existing function to then call it, eg 或者,您可以使用现有函数来调用它,例如

runPromiseGenerator(function *promiseGenerator() {
  yield p.execute();

  // do something after execution
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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