JavaScript - 等待/阻塞,直到构造函数完全加载

时间:2015-07-10 21:01:27

标签: javascript asynchronous synchronous

我正在创建的JavaScript API具有以下结构:

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"
);

“引擎”实例需要几秒钟才能加载(1-2秒)。所以在那之前, 不应该调用engine.startCar

如何对构造函数(new Engine())进行内部更改,使其在完全加载之前不会返回实例?

3 个答案:

答案 0 :(得分:7)

这是JavaScript中的标准问题。通常,当您发出AJAX请求时会发生这种情况,但基于超时的延迟会产生相同的基本问题。

jQuery,以及大多数具有此类问题的库,通过使用返回" deferred"的初始方法来解决此问题。或者"承诺"可以用来说"当X完成时,做Y"。

最好通过示例解释。如果您在Engine构造函数中执行以下操作:

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

当您构建引擎时,您可以执行以下操作:

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

当然,由于客户端计算机的时间会有所不同,如果您可以使用window.setTimeout以外的某些逻辑来触发readyDeferred.resolve();,则会更好。例如,您可能在所有AJAX请求完成后触发它,这比任何特定的等待时间更可预测。

答案 1 :(得分:2)

你可以这样做:

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.net/tnpsfy62/1/

答案 2 :(得分:1)

试试这个:

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");
}

输出:

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

JSFiddle链接示例为here

祝你好运。