Javascript - 回调的优势

Inf*_*ngi 0 javascript callback node.js

我在理解回调方面有一点问题。我在过去 2 天内阅读了很多内容,我所了解的内容如下(如果我错了,请纠正我):

JavaScript 是一种单线程语言,您可以进行同步和异步编程。同步意味着,每条语句在执行之前等待前一条语句完成。这可能会导致麻烦,因为例如,如果与数据库的连接需要很多时间,则前一个之后的语句必须等待。最后,这是非常糟糕的,这就是为什么最好在 Javascript 中进行异步编程,因为异步代码不必等待,代码可以继续运行,用户不必等待。

异步编程需要回调(高阶函数)。

现在我尝试通过很多教程等编写一个小例子。

function testCallback(a,callback){
    console.log('1.function and given parameter: '+a);
    callback(10);
}    

testCallback(5 , function(x){
    console.log("2.function and given parameter of 1. function: "+x);
});
Run Code Online (Sandbox Code Playgroud)

那正确吗?输出是:

1.function and given parameter: 5
2.function and given parameter of 1. function: 10
Run Code Online (Sandbox Code Playgroud)

我不明白,这段代码有什么好处,因为我认为这仍然会导致麻烦?如果“console.log('1.function and....') 有问题,callback(10) 函数会不会停止?

谢谢你的帮助!

T.J*_*der 5

JavaScript 是一种单线程语言...

不,不是。该语言没有提及线程。不过,大多数环境为每个全局环境提供一个线程(并且在浏览器上,您可以创建更多线程,通过消息传递进行互操作)。NodeJS 只提供一个线程。某些环境(例如 JDK 上的 Rhino 或 Nashorn)提供真正的多线程(以及可能涉及的所有优点和麻烦)。

使用回调不会使代码异步。例如,您的示例不是异步的。考虑:

function testCallback(a,callback){
    console.log('1.function and given parameter: '+a);
    callback(10);
}    

console.log("Before the call");
testCallback(5 , function(x){
    console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Run Code Online (Sandbox Code Playgroud)

请注意我们是如何After the call直到之后 才看到的2.function and given parameter of 1. function: 10。如果回调是异步的,我们之前会看到它:

function testCallback(a,callback){
    console.log('1.function and given parameter: '+a);
    setTimeout(function() { // Using setTimeout
      callback(10);         // to make this call
    }, 0);                  // asynchronous
}    

console.log("Before the call");
testCallback(5 , function(x){
    console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Run Code Online (Sandbox Code Playgroud)

回调是同步调用还是异步调用完全取决于您将其传递给的函数的作用。比如,被调用的回调Array#sort是同步调用的,但是被调用的回调setTimeout是异步调用的。

对于异步代码,它必须启动一个操作,然后在稍后完成该操作,从而触发回调。setTimeout这样做,就像正确使用 ajax 一样,还有很多其他事情。


请注意,回调目前是您处理异步行为的方式(如上述的简单回调,或promise回调),但下一个规范(ES2017)将定义内置语言语义,用于以async和的形式处理没有回调的异步await。如果您使用 Babel 之类的工具进行转译,您今天就可以使用该语法。