【问题标题】:Will yield expression block if execute asynchronous operation?如果执行异步操作会产生表达式块吗?
【发布时间】:2014-10-17 03:18:21
【问题描述】:

我了解到,当我们调用next() 时,代码会一直运行到yield 关键字,而next() return 会保存这个值。我的问题是,如果yield表达式在做一个异步操作,比如执行一个文件io或者http请求,而在异步调用完成之前,我们调用next,是不是代码还是会阻塞,或者即使异步操作还没有完成就立即恢复运行?为什么?

function * generator(){
  yield http.get('http://google.com');
  yield http.get('http://yahoo.com');
}
var gen = generator();
var a = gen.next();
var b = gen.next(); 

如果google.com的请求没有完成,yahoo.com的请求会立即发送吗?或者它必须阻止并等待谷歌的请求完成?

【问题讨论】:

    标签: javascript generator yield


    【解决方案1】:

    如果你使用的“get”方法是anynchronous,它会立即返回(非阻塞)。这意味着即使 google.com 尚未完成,yahoo.com 的请求也会被发送。

    【讨论】:

      【解决方案2】:

      您发布的代码不会等待每个http.get 请求执行。但是,可以通过更改生成器的使用方式来做到这一点。

      以下代码展示了如何使用回调和生成器实现异步睡眠功能:

      function wait(ms) {
          return function (cb) {
              setTimeout(cb, ms);
          };
      }
      
      function * generator(startTime) {
          console.log('start ' + (Date.now() - startTime));
          yield wait(1000);
          console.log('stop ' + (Date.now() - startTime));
      }
      
      console.log("Using generator asynchronously")
      var gen2 = generator(Date.now());
      
      gen2.next().value(function () {
          gen2.next();
      });
      

      但是仍然可以忽略回调并立即返回。

      console.log("Using generator synchronously")
      var gen1 = generator(Date.now());
      gen1.next();
      gen1.next();
      

      对于您发布的代码,让http.get 返回Promise 是最有意义的。在这种情况下,您可能会有类似这样的代码:

      function * generator(){
          var google = yield http.get('http://google.com');
          var yahoo = yield http.get('http://yahoo.com');
      }
      
      var gen = generator();
      
      loop(gen);
      
      function loop(gen, next) {
          var result = gen.next(next);
      
          if (!result.done) {
              result.value.then(function (value) {
                  loop(gen, value)
              });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-20
        • 2019-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        相关资源
        最近更新 更多