发电机+承诺组合;控制流程说明

时间:2015-08-15 17:20:50

标签: node.js promise generator event-loop

使用https://www.promisejs.org/generators/处的一些代码,我将这个测试脚本放在一起(可能不相关,但我通过执行regenerator --include-runtime gentest.js > gentest-out.js && node gentest-out.js来运行它):

function async(makeGenerator){
  return function () {
    var generator = makeGenerator.apply(this, arguments);

    function handle(result){
      // result => { done: [Boolean], value: [Object] }
      console.log('  entered handle, result:', result);
      if (result.done) {
          console.log('  done, returning result.value:', result.value);
          return Promise.resolve(result.value);
      }

      console.log('  not done yet, returning promise');
      return Promise.resolve(result.value).then(function (res){
          console.log('    inside then.. res is', res);
          var me = generator.next(res);
          console.log('    generator.next(' + res + ') =', me);
        return handle(me);
      }, function (err){
        return handle(generator.throw(err));
      });
    }

    try {
      return handle(generator.next());
    } catch (ex) {
      return Promise.reject(ex);
    }
  }
}

var get = async(function*() {
    var left = new Promise(function(resolve,reject) {
        console.log('in promise object');
        setTimeout(function() {
            console.log('  in promise timeout function');
            setTimeout(function() {
                console.log('    in second timeout function');
                resolve(1)
            }, 10000);
        }, 3000)
    });
    console.log('got to before right=5');
    var right = 5;
    console.log('yield left:', yield left);
    console.log('got to after yield left');
    console.log('yield right:', yield right);
    console.log('returning');
    return 
});

console.log('get is instance of Promise before call:', get instanceof Promise)
console.log('get is instance of promise once called:', get() instanceof Promise);

结果是:

get is instance of Promise before call: false
in promise object
got to before right=5
  entered handle, result: { value: {}, done: false }
  not done yet, returning promise
get is instance of promise once called: true
  <long pause here>
  in promise timeout function 
    <longer pause here>
    in second timeout function 
    inside then.. res is 1
yield left: 1
got to after yield left
    generator.next(1) = { value: 5, done: false }
  entered handle, result: { value: 5, done: false }
  not done yet, returning promise
    inside then.. res is 5
yield right: 5
returning
    generator.next(5) = { value: undefined, done: true }
  entered handle, result: { value: undefined, done: true }
  done, returning result.value: undefined

我的问题是:

  1. 为什么初始result.value调用的generator.next()相等 到{}?不应该是分配给左边的Promise对象吗?
  2. 看起来手柄里面的Promise.resolve(result.value) 功能阻塞。我期待将承诺退回 .then方法在下一个tick上运行。相反,它似乎 在{.then方法'之前,Promise.resolve不会失去控制权 回调执行resolve(1)。那是怎么回事? 编辑 - 我在思考。然后在下一个刻度执行,但事件循环中没有其他内容,所以它看起来很阻塞......但它仍然没有解释为什么不立即返回Promise对象。

0 个答案:

没有答案