【问题标题】:Why is node.js generator not working as expected?为什么 node.js 生成器没有按预期工作?
【发布时间】:2016-10-28 10:39:45
【问题描述】:

给定以下两个代码sn-ps,为什么事务对象在工作情况下可见,而在其他情况下不可见?

工作案例:

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;
});

是否可以在第二种情况下使交易可见?

【问题讨论】:

  • 不,不在c的范围内。

标签: javascript node.js promise generator co


【解决方案1】:

这是因为函数作用域的工作方式。在工作示例中,transaction 是一个变量,如果 db.transaction 函数的范围以及其中的所有回调和函数都是可见的。但是,当您在 db.transaction 范围之外定义生成器函数时,生成器函数只能访问其自己的变量和父范围内的任何变量。

您可以在此处找到有关 javascript 函数范围的更多信息,例如:http://ryanmorr.com/understanding-scope-and-context-in-javascript/

【讨论】:

  • c 变量是在作用域之外定义的,所以它是全局使用的。你的似乎没有意义。
  • 是的,我指的是transaction变量,它不是全局变量,而是传递给db.transaction函数的回调的局部变量
【解决方案2】:

为什么事务对象在工作情况下可见,而在其他情况下不可见?

闭包。当一个函数对象被创建时,它只是捕获了周围范围内的所有变量。在第一种情况下,当生成器函数被创建时,它的周围范围内有一个名为transaction 的变量。因此,当它实际被调用时,transaction 在作用域中是可用的。

但是在第二种情况下,在创建生成器函数时,transaction 不可用。


要解决此问题,您需要明确传递 transaction 对象。可能是这样的

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

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

【讨论】:

  • 有道理!是否可以稍微更改代码以使其工作,例如在 db.transaction(...) 内部调用生成器,同时仍在其外部定义函数?
  • @Scholle 更新答案中的示例有帮助吗?
猜你喜欢
  • 1970-01-01
  • 2014-08-04
  • 2021-01-03
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多