admin管理员组

文章数量:1335832

The JavaScript API that I am creating has the following structure:

var engine = new Engine({
    engineName: "TestEngine",
    engineHost: "localhost"
});

// I don't want to proceed to the next line until Engine is fully loaded
// But the following part of the API is immediately called before the above is loaded
engine.startCar(
    "car_name",
    "car_id"
);

The "Engine" instance takes a few seconds to load (1-2 seconds). So until then, engine.startCar should NOT be called.

How do I make internal changes to the constructor ( new Engine() ) such that, it doesn't return the instance until it is fully loaded?

The JavaScript API that I am creating has the following structure:

var engine = new Engine({
    engineName: "TestEngine",
    engineHost: "localhost"
});

// I don't want to proceed to the next line until Engine is fully loaded
// But the following part of the API is immediately called before the above is loaded
engine.startCar(
    "car_name",
    "car_id"
);

The "Engine" instance takes a few seconds to load (1-2 seconds). So until then, engine.startCar should NOT be called.

How do I make internal changes to the constructor ( new Engine() ) such that, it doesn't return the instance until it is fully loaded?

Share Improve this question asked Jul 10, 2015 at 21:01 BlueChips23BlueChips23 1,9516 gold badges34 silver badges57 bronze badges 2
  • 4 Run it in a callback - for instance, Promises. – Jared Farrish Commented Jul 10, 2015 at 21:03
  • 1 Or return a promise and add the call to engine.startCar as a continuation – Matt Burland Commented Jul 10, 2015 at 21:07
Add a ment  | 

3 Answers 3

Reset to default 7

This is a standard problem in JavaScript. Normally it occurs when you make AJAX requests, but timeout-based deferreds have the same basic issue.

jQuery, and most libraries with this sort of issue, solve this problem by having an initial method which returns a "deferred" or "promise" object that can be used to say "when X is done, do Y".

This is best explained by example. If you do the following in your Engine constructor:

function Engine(option) {
     var readyDeferred = new $.Deferred();
     this.ready = readyDeferred;
     window.setTimeout(1000, function() {
         readyDeferred.resolve();
     }
}

You when you build an engine you can simply do the following:

var engine = new Engine({...});
engine.ready.done(function() {
    // start your engines!
});

Of course, since times vary on client machines, it'd be even better if you could use some logic other than a window.setTimeout to trigger your readyDeferred.resolve();. For instance, you might trigger it when all of your AJAX requests have finished, which would be more predictable than any specific wait time.

You could do something like this:

function Engine(options, callback){ 
    this.engineName = options.engineName; 
    this.engineHost = options.engineHost; 

    //Wait for something to finish before calling the callback 
    var me = this; 
    setTimeout(function(){ 
        callback(me); 
    }, 1000); 

    this.startCar = function(){
        console.log(this.engineName); 
    }
}; 

var engine = new Engine({ 
    engineName: "TestEngine",
    engineHost: "localhost"
}, function(engine){ 
        //Run callback code 
        engine.startCar(); 
    }); 

http://jsfiddle/tnpsfy62/1/

Try this:

function Engine (params) {  
    console.log("In engine constructor");  
    console.log("In engine constructor - all done");  
    setTimeout(myStartEngine, 100);  
}

var engine = new Engine({
    engineName: "TestEngine",
    engineHost: "localhost"
});

// I don't want to proceed to the next line until Engine is fully loaded  
// But the following part of the API is immediately called before the above is loaded  

function myStartEngine() {
    console.log("Starting engine");

    engine.startCar(
        "car_name",
        "car_id"
    );

    console.log("Starting engine - done");
}

Output:

In engine constructor    
In engine constructor - all done    
About to start engine    
Starting engine - done    

Example JSFiddle link is here.

Best of luck.

本文标签: asynchronousJavaScriptWaitingblocking until constructor is completely loadedStack Overflow