Почему генератор node.js не работает должным образом?

Учитывая следующие два фрагмента кода, почему объект транзакции видим в рабочем случае, но не виден в другом случае?

Рабочий случай:

return db.transaction(function(transaction) {
  return co(function*() {
    // transaction is visible, do something with it -> works
  }
}

Не рабочий случай:

var c = co(function*() {
   // transaction is NOT visible -> does not work!
});

return db.transaction(function(transaction) {
  return c;
});

Можно ли сделать транзакцию видимой во втором случае?

2 ответа

Решение

почему объект транзакции виден в рабочем случае, но не виден в другом случае?

Затворы. Когда создается функциональный объект, он просто захватывает все переменные в окружающей области видимости. В первом случае, когда создается функция генератора, она имеет переменную transaction в окружающем объеме. Итак, когда он действительно вызывается, transaction доступно в объеме.

Но во втором случае, когда создается функция генератора, transaction не доступен.


Чтобы это исправить, вам нужно явно передать transaction объект вокруг. Может так

function c(transaction) {
  return co(function*() {
    // transaction will be available now
  });
}

return db.transaction(function(transaction) {
  return c(transaction);
});

Это из-за того, как работает область действия функции. В рабочем образце transaction переменная, видимая, если область действия db.transaction функция и все обратные вызовы и функции в нем. Однако, когда вы определяете функцию генератора вне области действия db.transaction функция генератора имеет доступ только к своей собственной переменной и любым переменным в родительской области видимости.

Вы можете найти больше информации о области действия функции в javascript здесь, например: http://ryanmorr.com/understanding-scope-and-context-in-javascript/

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