問題描述
鎖定一個 JavaScript 函數 (Lock a JavaScript Function)
I have a JavaScript function like the following.
function changeTheDom(var1, var2, var3) {
// Use DWR to get some server information
// In the DWR callback, add a element to DOM
}
This function is called in a couple of places in the page. Sometimes, in a loop. It's important that the elements be added to the DOM in the order that the changeTheDom
function is called.
I originally tried adding DWREngine.setAsync(false);
to the beginning of my function and DWREngine.setAsync(true);
to the end of my function. While this worked, it was causing utter craziness on the rest of the page.
So I am wondering if there is a way to lock the changeTheDom
function. I found this post but I couldn't really follow the else
loop or how the lockingFunction
was intended to be called.
Any help understanding that post or just making a locking procedure would be appreciated.
參考解法
方法 1:
Don't try to lock anything. The cleanest way is always to adapt to the asynchronous nature of your code. So if you have an asynchronous function, use a callback. In your particular case I would suggest that you split your function up in one part that is executed before the asych call and one part that is executed afterwards:
function changeTheDomBefore(var1, var2, var3) {
//some code
//...
asyncFunction(function(result){
//this will be executed when the asynchronous function is done
changeTheDomAfter(var1, var2, var2, result);
});
}
function changeTheDomAfter(var1, var2, var3, asynchResult) {
//more code
//...
}
asyncFunction
is the asynchronous function which, in this example, takes one argument ‑ the callback function, which then calls your second changeTheDom
function.
方法 2:
I think I finally got what you mean and I decided to create another answer, which is hopefully more helpful.
To preserve order when dealing with multiple asynchronous function calls, you could write a simple Queue class:
function Queue(){
var queue = [];
this.add = function(func, data) {
queue.push({func:func,data:data});
if (queue.length === 1) {
go();
}
};
function go() {
if (queue.length > 0) {
var func = queue[0].func,
data = queue[0].data;
//example of an async call with callback
async(function() {
func.apply(this, arguments);
queue.shift();
go();
});
}
}
};
var queue = new Queue();
function doit(data){
queue.add(function(result){
console.log(result);
}, data);
}
for (var i = 0; i < 10; i++) {
doit({
json: JSON.stringify({
index: i
}),
delay: 1 ‑ i / 10.0
});
}
FIDDLE
So everytime you invoke your async function, you call queue.add()
which adds your function in the queue and ensures that it will only execute when everything else in the queue is finished.
(by Snowy Coder Girl、basilikum、basilikum)