5

node.jsを使用しています。私はこのhandlers.jsファイルを持っています:

exports.Handlers = function(prefix) {
    this.prefix = prefix;
    this.db = new DBInstance();
};

exports.Handlers.prototype.getItemById = function(id) {
    var item = this.db.getItemById(id, function(error, item) {
        item.name = this.prefix + item.name;
        ...
        ...
    });
};

私が電話するとき:

var h = new Handlers();
h.getItemById(5);

コンテキストがハンドラーではなく、this.prefixが存在しないため、エラーが発生します。私はこれを使用してそれを修正することができます:

exports.Handlers.prototype.getItemById = function(id) {
    var scope = this;
    var item = this.db.getItemById(id, function(error, item) {
        item.name = scope.prefix + item.name;
        ...
        ...
    });
};

コンテキストをコールバックに渡すためのより良い方法はありますか?コンテキストをコールバックに渡すnodejsの一般的な方法は何ですか?

4

3 に答える 3

18

Nodeは、を含むECMAScript5を実装しますFunction.bind()

それがあなたが探しているものだと思います。

exports.Handlers.prototype.getItemById = function(id) {
    var item = this.db.getItemById(id, (function(error, item) {
        item.name = this.prefix + item.name;
        ...
        ...
    }).bind(this)); //bind context to function
};

これは機能しますが、クロージャをコールバックとして使用する場合、これを行う最も一般的な方法は、クロージャで使用できる変数にコンテキストを格納することです。

多くの場合、コールバックは深くなる可能性がありbind、各コールバックの呼び出しは重い可能性があるため、このメソッドはより一般的です。一方、一度定義するselfのは簡単です。

SomeObject.prototype.method = function(id, cb) {
    var self = this;
    this.getSomething(id, function(something) {
        //self is still in scope
        self.getSomethingElse(something.id, function(selse) {
            //self is still in scope and I didn't need to bind twice
            self.gotThemAll(selse.id, cb);
        });
    });
};
于 2013-01-26T19:57:41.237 に答える
1

この問題はNode.jsとは関係ありません。これは、JavaScriptの一般的な問題です。JavaScriptの通常の解決策はすでにわかっています。thisコンテキストを別の変数(呼び出した変数)にバインドscopeし、コールバック内でそれを使用してアクセスします。外側のコンテキスト。

この変数の一般名には、とが含まthatselfます。

ECMAScript 6(コードネーム「ハーモニー」)には、関数を外部コンテキストにバインドする、いわゆるファットアロー演算子を使用した解決策がある可能性があります。今日それを試してみたい場合は、ES6互換の構文に焦点を当てたMicrosoft製のJavaScript用のプリコンパイラであるTypeScriptをチェックしてみてください。次に、コールバックは次のようなものになります

foo(() => { console.log(this.bar); });

それ以外の:

var that = this;
foo(function () { console.log(that.bar); });

完全を期すために、jQuery(およびその他のフレームワーク)のbind関数は一般的に同様に機能します。例については、 http://api.jquery.com/bind/を参照してください。

HTH。

于 2013-01-26T19:33:10.440 に答える
-2

それが一般的な方法です。またはscopeという名前の変数が見つかります。self_self

後で編集:

別のコンテキスト内で関数を呼び出したい場合は、次のようにします。

getItemById.call(context, vars);
于 2013-01-26T19:31:42.400 に答える