如何正确处理回调堆栈

时间:2014-11-10 13:16:40

标签: javascript node.js

我有一个看起来像这样的模块:

function MyMod(){}

MyMod.prototype.doSomething = function(handler){
  //do stuff
  var callback = function(){
    //doStuff
    handler();
    
  };
  anotherModule.doSomething(callback);
}


module.exports = MyMod

这很好但是我不想在doSomething方法中嵌入实际的callBack方法,所以我尝试了以下内容:

    function MyMod(){}

    MyMod.prototype.doSomething = function(handler){
      this.handler = handler;
      anotherModule.doSomething(this.someCallBack);
    }

    MyMod.prototype.someCallBack = function(){
        //doStuff
        this.handler();
      }

    module.exports = MyMod

这似乎更清洁,更容易扩展,但这似乎不起作用。 我似乎注意到,在做这种方法时,他似乎失去了对象的上下文,而this.handler是未定义的。

如何在node.js中正确处理这样的概念?

1 个答案:

答案 0 :(得分:0)

JavaScript中的

this指的是当前上下文。您可以使用.apply.call更改上下文,例如:

var fn = function() {  
    console.log(this);  
};
fn.call({}); // {}
fn.call([1,2,3]); // [1,2,3]

这意味着当管道功能到其他模块等时,你必须关心this所指的是什么:

var moduleA = { 
    fn: function() { 
        // logic
        this.fn2();
    }, 
    fn2: function() {
        // more logic
    }
};
var moduleB = { 
    fn: function(callback) { 
        // logic
        callback();
    }
}; 

moduleB.fn(moduleA.fn); // TypeError: undefined is not a function 

这是因为当调用moduleA.fn时,上下文(this)被设置为全局上下文:moduleA.fn -> fn -> fn(),为了防止这种情况,您可以使用.bind(context)

var fn = function() { console.log(this, arguments) };
var fnBound = fn.bind({});

fnBound(); // {};
fnBound.call([1,2,3]); // {} even works if people are trying to change the context

专注于您的2.解决方案。

我们之前使用moduleAmoduleB进行了测试:

var moduleA = { 
    fn: function() { 
        // logic
        this.fn2();
    }, 
    fn2: function() {
        // more logic
    }
};
var moduleB = { 
    fn: function(callback) { 
        // logic
        callback();
    }
}; 

moduleB.fn(moduleA.fn.bind(moduleA)); // works 

糖:

var fn = function() { console.log(this); };

// Bind context = {}; 
// Bind arguments[0] = 1
// Call with arguments = [2, 3]
// Final: context = {}, arguments = [1,2,3]
fn.bind({}, 1)(2, 3);