最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

design patterns - Javascript: Callback in constructor - Stack Overflow

programmeradmin4浏览0评论

I'm trying to write OO javascript for an object that has an expensive initialization process that will callback a function when its done.

The problem is that the caller needs to use the functions of that same object in the callback routine, and the object doesn't exist yet:

// ctor for foo object
function foo(callback) {

    // do slow initialization here..

    // callback when done
    callback();
};

foo.prototype = function() {

    return {
        // doStuff method
        doStuff: function() {
          alert('stuff done');
        }
    };        
}();

// instantiate the foo object, passing in the callback
var f = new foo(function() {

    //Uncaught TypeError: Cannot call method 'doStuff' of undefined 
    f.doStuff();

});​

jsFiddle What am I missing here?

I'm trying to write OO javascript for an object that has an expensive initialization process that will callback a function when its done.

The problem is that the caller needs to use the functions of that same object in the callback routine, and the object doesn't exist yet:

// ctor for foo object
function foo(callback) {

    // do slow initialization here..

    // callback when done
    callback();
};

foo.prototype = function() {

    return {
        // doStuff method
        doStuff: function() {
          alert('stuff done');
        }
    };        
}();

// instantiate the foo object, passing in the callback
var f = new foo(function() {

    //Uncaught TypeError: Cannot call method 'doStuff' of undefined 
    f.doStuff();

});​

jsFiddle What am I missing here?

Share Improve this question asked Dec 22, 2012 at 4:03 saillesaille 9,1915 gold badges47 silver badges58 bronze badges 2
  • I fail to see why you need a callback to a function that pletes synchronously where the callback does not return a useful value. – icktoofay Commented Dec 22, 2012 at 4:12
  • 1 The 'slow initialization' actually involves a 3rd party library which expects to be passed the callback function. – saille Commented Dec 22, 2012 at 6:20
Add a ment  | 

3 Answers 3

Reset to default 7

It should be a simple fix. First, make sure your callback is called with the this object set to the current object

function foo(callback) {
    // do slow initialization here..

    callback.call(this);
};

Then adjust how you make your callback

var f = new foo(function() {
    this.doStuff();
});​

Here's your updated fiddle

Here's why it doesn't work: when JavaScript is executing the code, before it can set f, it needs to evaluate the new foo(...) expression. Inside of the constructor, it calls the callback. JavaScript still has not set f since the expression has not yet finished. As soon as the constructor finishes, f is set correctly, but it never gets there because you try to use f inside of the callback when it is still undefined.


You could call the callback on the next iteration through the event loop, so rather than:

callback();

You'd do:

setTimeout(callback, 0);

This would only work if you're already assuming that it pletes asynchronously, though.

Your approach is the intrinsic issue. Define doStuff within the constructor. The call as such:

var f = new Foo();
f.doStuff();

You can also create an init method to run whenever a new object is created. But, you should do this within the scope of the constructor... do not pass a callback to a constructor.

发布评论

评论列表(0)

  1. 暂无评论