2016-06-26 3 views
1

以下の2つのコードスニペットがあると、トランザクションオブジェクトは作業中のケースでは表示されますが、それ以外のケースでは表示されないのはなぜですか?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ケース内のトランザクションを可視化することは可能ですか?

+0

いや、それは 'C'の範囲ではありません。 – zerkms

答えて

3

なぜトランザクションオブジェクトは作業中のケースで表示できますが、それ以外の場合は表示されませんか?

クロージャ。関数オブジェクトがで作成された場合、それは周囲のスコープ内のすべての変数をキャプチャするだけです。最初のケースでは、ジェネレータ関数が作成されると、それは周囲の範囲にtransactionと呼ばれる変数を持っています。したがって、実際に呼び出されるときには、transactionがスコープ内で使用可能です。

しかし、2番目のケースでは、ジェネレータ関数が作成されると、transactionは使用できません。


これを修正するには、transactionオブジェクトを明示的に渡す必要があります。多分このように

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

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

意味があります!コードを少し変更して動作させることは可能ですか? db.transaction(...)の中でジェネレータを呼び出して、それ以外の関数を定義していますか? – Scholle

+0

@Scholle更新された回答の例は役に立ちますか? – thefourtheye

+0

はい、完璧です! – Scholle

0

これは機能範囲の仕組みのためです。作業サンプルでは、​​transactionは、db.transactionのスコープとその中のすべてのコールバックおよび関数のスコープで表示される変数です。しかし、ジェネレータ関数をdb.transactionのスコープの外に定義すると、ジェネレータ関数はそれ自身の変数と親スコープ内のすべての変数にのみアクセスできます。

あなたは、例えばここにJavaScriptで関数スコープの詳細情報を見つけることができます:http://ryanmorr.com/understanding-scope-and-context-in-javascript/

+0

c変数はスコープ外で定義されているため、グローバルに使用されます。あなたのことは意味をなさないと思われます。 –

+0

はい、グローバルではなく、 'db.transaction'関数に渡されるコールバックに対してローカルな' transaction'変数を参照していました –

関連する問題