所有的JavaScriptcallback是asynchronous的吗? 如果没有,我怎么知道哪些是?

我很好奇所有的JavaScriptcallback是否是asynchronous的,或者只是在某些情况下是这种情况。 此外,我确定JavaScript代码asynchronous(或使用asynchronousJavaScript的方法)是什么使浏览器和nodejs不同,所以我想知道在每种情况下构成真正的asynchronousJavaScript。

我的印象是,在下面的情况下,我实际上没有编写asynchronous代码。

function addOne(value){ value = value + 1; return value; } function simpleMap(values, callback){ for(i = 0; i < values.length; i++){ val = values[i]; val = callback(val); values[i] = val; } return values; } newValues = simpleMap([1,2,3], addOne); 

但是,例如,我知道jQuery的AJAXfunction是真正的asynchronous(不考虑现在可用的承诺)。 什么是使jQuery的AJAXasynchronous? 它是否涉及XHR请求,并且在浏览器中,所有的XHR请求都是asynchronous的?

我对nodejs环境有同样的问题。 如果节点中的某些东西像文件I / O,process.nextTick,setTimeout或setInterval那样只能是asynchronous的? 为什么当我用mongodb / mongoose进行数据库调用时,是asynchronous的? 幕后发生了什么事情呢?

是由环境预先确定的asynchronous“情况”? 或者有没有办法使自己的function真正的asynchronous,而不是利用环境的非常具体的function(如xhr,节点中的文件io,process.nexttick等)?

我很好奇,是否所有的JavaScriptcallback是asynchronous的

不,例如, Array#sort使用的callback不是asynchronous的,也不是由String#replace使用的callback。

你知道一个callback是否是asynchronous的唯一方法是从它的文档。 通常情况下,涉及外部资源(例如ajax调用)的请求是asynchronous的,其他的可能是也可能不是。

但是,例如,我知道jQuery的AJAX函数是真正的asynchronous…

不一定,因为目前jQuery仍然有async标志,你可以设置false来强制同步请求。 (这不是一个好主意,他们将删除,但你可以 .jQuery将标志传递给提供同步/asynchronous行为的底层浏览器对象。)

什么是使jQuery的AJAXasynchronous?

浏览器。 jQuery的ajax调用使用XMLHttpRequest对象(或在某些情况下,一个script元素),默认为浏览器提供的asynchronous操作。

或者有没有什么办法使自己的function真正的asynchronous,而不是利用环境的特定function…

直到最近,没有。 通过第5版规范,JavaScript 语言对线程和asynchronous性的整个概念基本上是沉默的; 只有当你进入环境时才会出现。 使asynchronous的唯一方法是使用主机提供的function,如nextTick (或任何asynchronous完成的各种操作)或浏览器上的setTimeout

在2015年6月的ECMAScript第6版规范中,他们将承诺引入语言。 callback挂钩到一个ES6的承诺, then 总是asynchronous调用(即使承诺已经解决了,当callback被附加),所以JavaScript现在语言级别具有asynchronous性。 所以,如果你实现你的函数,以便它返回一个promise,而不是接受一个callback函数,那么你就会知道被它调用的callback函数将被asynchronous触发。

要创build您自己的asynchronous函数,您必须使用解释器可能提供的其他asynchronous函数。

例如,这段代码定义了一个asynchronous的函数“addKeyHandler”。 但是这只是因为document.onKey被JS引擎asynchronous调用。 JavaScript引擎能够提供asynchronousfunction,因为操作系统提供了JS所使用的function。 操作系统反过来只能提供asynchronousfunction,因为硬件提供了它(称为硬件中断)。

但是,如果操作系统和硬件没有提供任何asynchronousfunction,它仍然可以写一个JS解释器。 但是,如果发生任何事件,则必须使用无限循环并检查每次迭代,然后调用适当的callback。 这将意味着CPU将始终处于满负荷状态。

 var keyCallbacks = []; var addKeyHandler = function(f) { keyCallbacks.push(f); }; document.onkeypress = function(e) { keyCallbacks.forEach(function(f) { f(e); }); }; addKeyHandler(function(e) { console.log(String.fromCharCode(e.charCode)); }); 

你自己调用的callback是常规函数调用,它们总是同步的。

某些本地API(例如,AJAX,地理位置,Node.js磁盘或networkingAPI)是asynchronous的,稍后将在事件循环中执行它们的callback。

如果您在asynchronouscallback中同步调用callback,则最终也会是asynchronouscallback。

简单地进行callback不会使函数asynchronous。 有许多函数采用函数参数但不是asynchronous的例子,例如ArrayforEach

对于一个function是asynchronous的,它需要执行一个asynchronous操作。 引入asynchronous性的方式可以是

  • 定时器函数setTimeoutsetInterval
  • nextTick特殊function, setImmediate
  • 执行I / O(侦听networking,查询数据库,读取或写入资源)
  • 订阅一个事件

根据文章“做callback使函数asynchronous?”