Комбинация генератор + обещание; объяснение потока управления

Используя некоторый код, найденный по адресу 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 выполняется на следующем тике. Вместо этого кажется, чтоPromise.resolve не теряет контроль, пока обратный вызов метода.then не выполнит resolve(1), Это то, что здесь происходит? Редактировать - я думаю. Затем выполняется на следующем тике, но в цикле событий больше ничего нет, поэтому он выглядит блокирующим... но он все равно не объясняет, почему объект Promise не возвращается немедленно.

0 ответов

Другие вопросы по тегам