如果应该使回调允许一个功能在被调用之前等待另一个功能完成,为什么以下功能不起作用?
function doHomework(subject, callback) {
setTimeout(function() {
console.log(`Starting my ${subject} homework.`)
}, 1000)
callback()
}
function finishHomework() {
console.log('Homework Finished!')
}
doHomework('chemistry', finishHomework)
这输出以下内容:
Homework Finished!
Starting my chemistry homework.
但这应该是另一种方式。为什么回调不等待setTimeout完成才被调用?
答案 0 :(得分:1)
您需要了解JS的执行模型。由于JS旨在在GUI中运行,因此它是事件驱动的,因此在事件循环中运行。这意味着主线程正在执行您的脚本,但是其他线程可以在主线程排队的就绪工作上工作。
for (;;)
if event = dequeueWork()
handleEvent(event)
else
sleep(SOME_TIME)
解释了脚本后,JS引擎会知道doHomework()
具有超时事件注册。超时就像其他语言的睡眠一样,但是由于这是一个事件循环模型,因此我们无法阻止GUI。因此,此功能实际上是由后台线程处理的。持续时间过去后,将通知主线程-这是在JS中处理所有IO的方式。
了解这一点,很容易看到发生了什么:在注册超时事件之后立即触发回调。
来自c-sharpcorner.com
要解决此问题,就像其他人提到的那样,您需要在超时的回调中调用该回调:
function doHomework(subject, callback) {
console.log(`Starting my ${subject} homework.`)
setTimeout(function() {
callback();
}, 1000);
}
function finishHomework() {
console.log('Homework Finished!')
}
doHomework('chemistry', finishHomework)
当然,我们所有人都还不够幸运,无法在开始1秒后完成作业;)
有用的资源:
答案 1 :(得分:0)
callback
是将来执行的某事物的名称,您的回调将来不会执行,而是在调用函数setTimeout
之后立即执行。
您真正想做的是将来一秒钟调用函数finishHomework
,因此,您必须将callback
放在函数setTimeout
的处理程序中,如下所示:
function doHomework(subject, callback) {
setTimeout(function() {
console.log(`Starting my ${subject} homework.`);
// Here depends of your needs, in this case the callback
// will be called after all the previous logic is executed.
callback()
}, 1000)
}
function finishHomework() {
console.log('Homework Finished!')
}
doHomework('chemistry', finishHomework)