在下面的代码中,我不明白为什么要调用这两个回调函数。 callback01有意义,因为它在调用load之前在回调数组中。另一方面,callback02在调用加载之前没有放入数组,但控制台显示它被调用。
var callbacks = [];
function addCallback(func) {
callbacks.push(func);
}
function load(img_url) {
var img = new Image();
img.onload = function() {
console.log('loaded.');
callbacks.forEach(function(func) { func(); } )
};
img.src = img_url;
}
addCallback(function() { console.log('callback01'); });
load('img/image01.png');
addCallback(function() { console.log('callback02'); });
答案 0 :(得分:1)
两个回调都会触发,因为图像加载后回调会触发。加载图像需要几毫秒,这是代码加载和添加两个回调的充足时间。
据推测,这就是浏览器执行代码的方式:
// 1 - add first callback
addCallback(function() { console.log('callback01'); });
// 2 - tell JS to begin loading
load('img/image01.png');
// 3 - add second callback
addCallback(function() { console.log('callback02'); });
// 4 - image loads in the background
// 5 - the img.onload function fires and invokes each callback
// 5.a - callback 1 fires
// 5.b - callback 2 fires
答案 1 :(得分:0)
第二个addCallback行可能在load()完成时完成。如果您不希望此时使用callback02,请在load()函数定义的末尾添加它(如果这是一个选项)。
答案 2 :(得分:0)
在对javascript运行的浏览器的事件循环进行一些研究之后,似乎发生了这样的事情:
由于javascript是在单个线程中执行的,因此当代码执行时,控件不会返回到浏览器以处理事件,直到所有代码都被执行完毕。
将img.onload回调插入到事件队列中,执行callback02的addCallBack,将其自身添加到数组中,此时控制从javascript返回到事件循环,两个回调都可用调用onload回调。
var callbacks = [];
function addCallback(func) {
console.log('addCallback: ' + (new Date()));
callbacks.push(func);
}
function load(img_url) {
var img = new Image();
img.onload = function() {
console.log('load: ' + (new Date()));
callbacks.forEach(function(func) { func(); } )
};
img.src = img_url;
}
function badsleep(duration) {
var now = new Date().getTime();
while((new Date()).getTime() < (now + duration));
}
addCallback(function() { console.log('callback01: ' + (new Date())); });
load('img/image01.png');
badsleep(2000);
addCallback(function() { console.log('callback02: ' + (new Date())); });
console.log('execution continues: ' + (new Date()));
结果:
addCallback: Sat Jul 05 2014 08:56:05
addCallback: Sat Jul 05 2014 08:56:07
execution continues: Sat Jul 05 2014 08:56:07
load: Sat Jul 05 2014 08:56:07
callback01: Sat Jul 05 2014 08:56:07
callback02: Sat Jul 05 2014 08:56:07
所以看起来这是因为尽管似乎在加载函数之前和之后添加了回调,但这两个回调都在数组中。我希望无论如何,因为这使代码直截了当。