Почему генератор 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/