在我提到的this文章中,做出了以下声明:
回调是一种确保某些代码在其他代码已经完成执行之前不会执行的方法。
然后,本文通过一个示例继续说明这一点:
function doHomework(subject, callback) {
alert(`Starting my ${subject} homework.`);
callback();
}
doHomework('math', function() {
alert('Finished my homework');
此后,文章指出:
如您所见,如果在控制台中键入上述代码,您将收到两个背对背的警报:“开始作业”警报,然后是“作业完成”警报。
似乎暗示通过使用回调,可以确保所需的代码执行顺序。那就是您在完成作业之前开始作业。但是,我觉得我可能误解了本文的全部内容,因此仍然不理解回调和异步代码,因为当我使用setTimeout()减慢doHomework函数的第一部分时,代码将在以下位置执行(或至少返回)相反的顺序:
function doHomework(subject, callback) {
setTimeout(function(){
console.log(`Starting my ${subject} homework.`);
}, 500);
callback();
}
doHomework('math', function() {
console.log('Finished my homework');
});
我从中得到的结果是:
steve@Dell ~/my-app $ node app.js
Finished my homework
Starting my math homework.
});
我在这里使用节点(因此console.log()替换了alert()),但我认为这并不重要。
在我看来,我已经错过了一些非常基础的知识,需要尝试并尝试了解我试图理解的内容,然后再尝试理解。
在此过程中提供的任何帮助将不胜感激。
获得大量反馈后,我认为作业类比没有帮助,因此我现在使用我引用的文章中的第一个代码示例。本文提供了以下代码:
function first(){
// Simulate a code delay
setTimeout( function(){
console.log(1);
}, 500 );
}
function second(){
console.log(2);
}
first();
second();
上面在控制台中返回2,然后返回1。
我尝试(没有成功)用以下方法将退货顺序倒换为1然后是2:
function first(callback){
setTimeout(function(){
console.log(1);
}, 500);
callback();
}
function second(){
console.log(2);
}
first(second);
我从Cleared(在被编辑之前)得到的答案是将callback()放在setTimeout()函数内。他使用了家庭作业示例,但此处包含此示例:
function first(callback){
setTimeout(function(){
console.log(1);
callback();
}, 500);
}
function second(){
console.log(2);
}
first(second);
我认为这与我想象中的文章更接近。尽管我猜想您正在做的事情以及您想发生的事情的确切背景,确定什么是对还是错,这似乎还是有道理的。
答案 0 :(得分:5)
通常,对回调的调用不是在函数的结束处,而是在完成重要操作后的 。
因此,如果我理解您的问题,则doHomework
函数应开始执行作业(这需要花费时间,在这种情况下为500毫秒),然后完成作业。因此,您认为重要的事情是console.log('Starting my ${subject} homework.');
,它“耗时500毫秒”(因为这是您需要做功课的时间)。
因此,您应该在console.log('Starting my ${subject} homework.');
之后将呼叫转到回调,即
function doHomework(subject, callback) {
setTimeout(function(){
console.log(`Starting my ${subject} homework.`);
callback();
}, 500);
}
doHomework('math', function() {
console.log('Finished my homework');
});
答案 1 :(得分:2)
通常,您在完成操作后会调用回调函数。
因此,您将setTimeout函数的内部和外部代码向后了。
function doHomework(subject, callback) {
console.log(`Starting my ${subject} homework.`);
setTimeout(function(){
console.log(`Finished my ${subject} homework.`);
callback();
}, 500);
}
答案 2 :(得分:1)
JavaScript中的回调用于异步编程中,在异步编程中,您不能确保上面的代码在下面的代码之前运行,例如从异步服务器中加载文件。
问题是,对于正常的顺序编程,您无法确保在程序运行时(例如,如果您运行脚本,一次可以设置变量,而另一次则可以)完全加载获取的数据。可能是未定义的,导致异步任务仍在运行),因此您设置了一个回调函数,该函数已连接到不同的状态,即。 ajax调用成功或错误。与正常编程流程的不同之处在于,您的程序只有在加载数据后才会停止(或者,在这种情况下,超时不会暂停您的程序,之后的代码会被计算出来,如果您不使用固定值)。
因此,为了确保您的代码在所需逻辑完成时能够运行,您必须传递一个回调函数,该回调函数在满足所需状态(即加载任务成功/错误或超时“完成”时执行) “。
家庭作业示例IMO并不是最佳示例,因为它始终无法“等待” 500毫秒,因为它没有涉及实际用例。
在您的示例中,问题是您的“回调”不在代码的“异步”部分中,因此即使超时仍在“运行”,它也将在启动超时后立即执行。也许您以为SetTimeout是个问题,在我的javascript开头,我认为它更像是“暂停500毫秒”,但是它的“等待正常代码流中的500毫秒后执行作用域代码”
这里有更多信息,即使您不是javascript noob,我也可以推荐整个页面;) https://javascript.info/callbacks
答案 3 :(得分:1)
回调表示函数在起作用,例如递归。
让我给你举个例子:
每天我们进食然后睡觉。但是在JS代码中,JS is an impatient language
与PHP不同。这是示例代码:
// Consuming 3s to eating(just an example, not really 3s)
function eating() {
setTimeout(function() {
console.log('Eating...');
}, 3000);
}
// Then go to sleep
function sleep() {
console.log('Z..Z..Z');
}
eating();
sleep();
但是您在...之后立即入睡(当我们运行代码时,它先运行睡眠然后再吃())
为确保一切正常,这意味着您仅在吃完饭后上床睡觉。因此,我们需要eating()
来说明何时启动sleep()
:
// Consuming 3s to eating(just an example, not really 3s)
function eating(callback) {
setTimeout(function() {
console.log('Eating...');
callback() // the function which will be proceeded after "Eating..."
}, 3000);
}
// Then go to sleep
function sleep() {
console.log('Z..Z..Z');
}
// call the function
eating(function() {
sleep();
});
是的!现在,我认为您可以在代码中使用回调!
您可以在每个JQuery
代码中看到它:
$("#hide").click(function(){ //the click() function call the function inside it which is callback
$("p").hide();
});
$("#show").click(function(){
$("p").show();
});