JavaScript - Waiting/blocking 直到构造函数完全加载
JavaScript - Waiting/blocking until constructor is completely loaded
我正在创建的 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"
);
"Engine" 实例加载需要几秒钟(1-2 秒)。所以直到那时,
engine.startCar
不应被调用。
如何对构造函数 (new Engine()
) 进行内部更改,使其在完全加载之前不会 return 实例?
你可以这样做:
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();
});
这是JavaScript中的标准问题。通常它会在您发出 AJAX 请求时发生,但基于超时的延迟具有相同的基本问题。
jQuery,以及大多数有此类问题的库,通过初始方法解决这个问题,其中 returns 一个 "deferred" 或 "promise" 对象可以是过去常说 "when X is done, do 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 请求完成时触发它,这比任何特定的等待时间都更可预测。
试试这个:
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 link 是 here。
祝你好运。
我正在创建的 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"
);
"Engine" 实例加载需要几秒钟(1-2 秒)。所以直到那时,
engine.startCar
不应被调用。
如何对构造函数 (new Engine()
) 进行内部更改,使其在完全加载之前不会 return 实例?
你可以这样做:
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();
});
这是JavaScript中的标准问题。通常它会在您发出 AJAX 请求时发生,但基于超时的延迟具有相同的基本问题。
jQuery,以及大多数有此类问题的库,通过初始方法解决这个问题,其中 returns 一个 "deferred" 或 "promise" 对象可以是过去常说 "when X is done, do 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 请求完成时触发它,这比任何特定的等待时间都更可预测。
试试这个:
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 link 是 here。
祝你好运。