node js将上下文传递给回调

时间:2013-01-26 19:14:13

标签: node.js

我正在使用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将上下文传递给回调的常用方法是什么?

3 个答案:

答案 0 :(得分:17)

Node实现了ECMAScript 5,其中包含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);
        });
    });
};

答案 1 :(得分:1)

这个问题与Node.js无关,这是JavaScript中的一个普遍问题 - 你已经找到了JavaScript中的常用解决方案:将this上下文绑定到另一个变量(你调用的那个变量scope 1}}),并在回调中使用它来访问外部上下文。

此变量的常用名称包括thatself

可能是ECMAScript 6(代号“和谐”)中的一个解决方案,它与所谓的胖箭头操作符将一个函数绑定到一个外部上下文。如果你今天想玩它,你可能想看看TypeScript,这是一个由Microsoft制作的JavaScript预编译器,它专注于与ES6兼容的语法。然后你的回调变成了诸如

之类的东西
foo(() => { console.log(this.bar); });

而不是:

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

仅仅为了完整性:jQuery(和其他框架)bind函数通常类似。有关示例,请参阅http://api.jquery.com/bind/

HTH。

答案 2 :(得分:-1)

这是常见的方式。您会发现名为scopeself的{​​{1}} var。

稍后编辑:

如果你想在另一个上下文中调用一个函数,可以这样:

_self