简体   繁体   English

Node.js类模块系统

[英]Node.js Class Module System

I'm trying to create a module/class in node.js to measure asynchronous execution time but do not understand whats wrong with it. 我正在尝试在node.js中创建模块/类以测量异步执行时间,但不了解它的问题所在。 I created the following class "Measure.js" 我创建了以下类“ Measure.js”

var Measure = module.exports = function(param_timeout, param_cb) {

    this.timeout = param_timeout;
    this.cb = param_cb;
}

Measure.prototype = {
    startDate: "0",
    timeout:"0",
    cb:null,

    start : function() {
        this.startDate = new Date();
        console.log('started');
    },

    stop : function() {
        var stopDate = new Date();
        this.cb(null,(stopDate-this.startDate));
    }
}

I use it with the following code: 我将其与以下代码结合使用:

var Measure = require('./Measure.js');
measure1 = new Measure(100,function(err,result){console.log('result: ' + result)});
measure1.start();
//do something 
measure1.stop();

and it works just fine. 而且效果很好。 However, if I try this: 但是,如果我尝试这样做:

var Measure = require('./Measure.js');
measure1 = new Measure(100,function(err,result){console.log('result: ' + result)});
measure1.start();
//do something 
setTimeout(measure1.stop,100);

it doesn't work and throws a TypeError: 它不起作用并抛出TypeError:

TypeError: Object #<Object> has no method 'cb'

Whats wrong with my code? 我的代码有什么问题?

When you directly call object's method, this inside the method referred to your object, but when you try to use it as argument, this will referred to global object ( global or window ). 当您直接调用对象的方法时, this方法内部的该对象是您的对象,但是当您尝试将其用作参数时, this将引用全局对象( globalwindow )。

In your case better to replace 在你的情况下最好更换

setTimeout(measure1.stop,100);

with

setTimeout(function() { measure1.stop(); }, 100);

More about this behavior: http://bonsaiden.github.com/JavaScript-Garden/#function.this 有关this行为的更多信息: http : //bonsaiden.github.com/JavaScript-Garden/#function.this

The dreaded timeout-switch-context bug strikes again! 可怕的超时切换上下文错误再次出现! You see what you see because this object in function called by setTimeout is not measure1 - it's global (= window , when this script is executed in browser). 您看到的是您看到的,因为setTimeout调用的函数中的this对象不是measure1它是global (= window ,在浏览器中执行此脚本时)。 Quoting the MDN : 引用MDN

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. setTimeout()执行的代码在与调用它的函数不同的执行上下文中运行。 As a consequence, the this keyword for the called function will be set to the window (or global ) object, it will not be the same as the this value for the function that called setTimeout . 结果,被调用函数的this关键字将被设置为window (或global )对象,它将与名为setTimeout的函数的this值不同。

It's quite easy to check, by the way: 顺便说一下,这很容易检查:

stop: function() {
  var stopDate = new Date();
  if (! this.cb) { 
    console.log(this); 
  } // *Window*/_display...
}

... and to fix as well: ...并进行修复:

setTimeout(function() { 
  measure1.stop(); 
}, 100);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM