所有的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…
直到最近,没有。 通过第五版规范,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的例子,例如
Array
的forEach
。对于一个function是asynchronous的,它需要执行一个asynchronous操作。 引入asynchronous性的方式可以是
- 定时器函数
setTimeout
,setInterval
nextTick
特殊function,setImmediate
- 执行I / O(侦听networking,查询数据库,读取或写入资源)
- 订阅一个事件
根据文章“做callback使函数asynchronous?”