0

我读过回调使 JavaScript 异步。但我不确定我是否理解了解释。这就是我得到的

回调函数允许我们异步执行操作,因为它们确保回调之前的行在加载下一行之前完全完成。

真的吗?谢谢

4

2 回答 2

6

首先,它不是启用任何东西的回调。node.js 甚至基于浏览器的 javascript 中的给定操作要么是异步的,要么不是异步的。它实际上与回调无关,尽管回调通常用于传达异步操作的结果。

例如,Javascriptarray.forEach()使用回调,但它不是异步的。因此,异步操作是异步的,因为它们的底层实现是非阻塞的。您通过调用函数开始操作,操作在后台继续,其余代码继续运行。同时,当异步操作完成时,它通常需要告诉你的代码它已经完成并且可能会传达一些结果。回调函数是用于传达异步操作完成的选定机制。

我读过回调使 JavaScript 异步。

不,这不是真的。回调也可以与同步操作一起使用。仅仅因为使用回调不会使任何事情异步。操作的底层本机代码实现必须是异步的(例如 Ajax 调用或其他网络操作)。回调用于传达异步操作的结果。它们也有许多其他非异步用途。因此,回调只是异步操作中使用的一种工具,回调也是具有许多其他用途的工具。你不能说callback === asynchronous

回调函数允许我们异步执行操作,因为它们确保回调之前的行在加载下一行之前完全完成。

很难准确地说出你的意思,但对我来说这听起来是错误的。使用异步操作时,代码通常不会按照文件中列出的顺序执行。例如,如果您这样做:

console.log("async start");
callSomeAsyncOperation(function(result) {
    console.log("async done");
});
console.log("I'm here now");

您会在日志中看到:

async start
I'm here now
async done

回调和事件队列解释

了解异步操作的工作原理也可能很有用。Javascript 在事件队列中工作。给定的 Javascript 代码序列运行到完成。完成后,引擎会在事件队列中查看是否还有要处理的事件。如果是这样,则队列中的第一个事件被拉出并调用为该事件注册的回调。这将开始运行新的 Javascript 代码序列。该代码将继续运行,直到完成。完成后,引擎会检查另一个事件。如果有,则通过调用与该事件关联的回调来处理它。当没有更多事件要处理时,引擎进入睡眠状态等待下一个事件。当事件发生时(在主要的 Javascript 主题之外),

在编写 Javascript 时,您通常会为事件注册和事件处理程序。这在 Javascript 中的工作方式是您说出您感兴趣的事件(其中可能还包括指定一些其他信息,例如您正在寻找事件的对象),然后您传递它是一个函数引用。本质上,您是在告诉 Javascript 引擎您希望它在此事件发生时调用您的函数引用。这种类型的函数引用称为“回调”。它只是一个普通函数,但使用它的上下文称为“回调”,因为其他一些代码会在未来某个时间通过执行您的函数来“回调”您。然后,您可以在可以响应该事件的该函数引用(该回调函数内部)中放置适当的代码。根据事件的类型,您可能只被调用一次,或者它可能会在每次事件发生时调用您。

您可以在这些参考资料中阅读有关此事件队列和回调如何工作的更多信息:

在节点中等待回调时运行任意代码?

非阻塞http服务器中的阻塞代码

Javascript/Node 中从不执行用户代码的隐藏线程:是否可能,如果可能,是否会导致竞争条件的神秘可能性?

JavaScript 如何在后台处理 AJAX 响应? (写的是浏览器,但概念是一样的)

于 2015-10-08T00:44:13.507 回答
1

首先,让我们了解一下什么是回调根据定义):

在计算机编程中,回调是一段可执行代码,它作为参数传递给其他代码,期望在某个方便的时间回调(执行)该参数。调用可以像在同步回调中​​一样立即进行,也可以像在异步回调中那样在稍后发生。在所有情况下,目的是将函数或子例程指定为实体,根据语言,它或多或少类似于变量。


现在,谈到 Javascript,回调并不总是异步的。例如:

function syncOperation(callback) {
  callback();
}

syncOperation(function() {
  console.log('a');
  console.log('b');
});

console.log('c');

该回调是同步的,因为它不进行任何异步操作。如果你打开你的控制台并运行上面的代码,你会看到它会记录a,然后b,然后c


现在,让我们看一个异步示例:

function asyncOperation(callback) {
  setTimeout(callback, 0);
}

asyncOperation(function() {
  console.log('a');
  console.log('b');
});

console.log('c');

您将首先看到c,然后a,和b。那是因为该setTimeout函数是异步运行的。

一些内置的 Javascript 函数是异步的,它们会运行,并且在某些时候,它们会调用你作为参数传递的函数back。这就是为什么如果你这样做:

var a = 'text';
setTimeout(function() { a = 'new text'; }, 0);
console.log(a);

您将在控制台中看到text,因为它会在变量更改之前运行。

于 2015-10-08T00:48:36.127 回答