Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
所有javascript回调都是异步的吗?如果没有,我如何知道哪些是?_Javascript_Node.js_Asynchronous_Synchronous - Fatal编程技术网

所有javascript回调都是异步的吗?如果没有,我如何知道哪些是?

所有javascript回调都是异步的吗?如果没有,我如何知道哪些是?,javascript,node.js,asynchronous,synchronous,Javascript,Node.js,Asynchronous,Synchronous,我很好奇是否所有javascript回调都是异步的,或者是否只有在某些情况下才是异步的。另外,我确定浏览器和NodeJ之间javascript代码异步(或使用异步javascript的方式)的不同之处,因此我想知道在每种情况下,真正的异步javascript是由什么组成的 我的印象是,在下面的场景中,我实际上并没有编写异步代码 function addOne(value){ value = value + 1; return value; } function simpleMap(va

我很好奇是否所有javascript回调都是异步的,或者是否只有在某些情况下才是异步的。另外,我确定浏览器和NodeJ之间javascript代码异步(或使用异步javascript的方式)的不同之处,因此我想知道在每种情况下,真正的异步javascript是由什么组成的

我的印象是,在下面的场景中,我实际上并没有编写异步代码

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);
函数addOne(值){
值=值+1;
返回值;
}
函数simpleMap(值,回调){
对于(i=0;i
然而,例如,我知道jQuery的AJAX函数是真正异步的(不考虑现在可用的承诺)。是什么使jQuery的AJAX异步化的?它涉及XHR请求,并且在浏览器中,所有XHR请求都是异步的,这是否很简单

对于nodejs环境,我有同样的问题。节点中的某些内容只有在涉及文件i/o、process.nextTick、setTimeout或setInterval之类的内容时才能是异步的吗?为什么当我使用mongodb/mongoose进行数据库调用时,会是异步的?幕后到底发生了什么使事情变得如此

异步“情况”是由环境预先确定的吗?或者,是否有某种方法可以使自己的功能真正异步,而不用利用环境中非常特定的功能(例如xhr、节点中的文件io、process.nexttick等)

我很好奇是否所有javascript回调都是异步的

否。例如,
Array#sort
使用的回调不是异步的,
String#replace
使用的回调也不是异步的

知道回调是否异步的唯一方法是从它的文档中。通常,涉及外部资源请求(例如ajax调用)的请求是异步的,而其他请求可能是异步的,也可能不是异步的

然而,例如,我知道jQuery的AJAX函数是真正异步的

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

是什么使jQuery的AJAX异步化的

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

或者是否有某种方法可以使自己的功能真正异步,而不用利用环境中非常特定的功能

直到最近,在第五版规范中,JavaScript语言基本上没有涉及线程和异步的整个概念;只有当你进入环境时,它才会出现。实现异步的唯一方法是使用主机提供的函数,例如NodeJS上的
nextTick
(或异步完成的各种操作中的任何一种)或浏览器上的
setTimeout


在2015年6月的ECMAScript第6版规范中,他们将承诺引入到该语言中。通过
then
连接到ES6承诺的回调总是异步调用的(即使在连接回调时承诺已经解决),因此JavaScript现在在语言级别上具有异步性。因此,如果您实现函数,使其返回承诺而不是接受回调,您将知道连接到它的
然后
回调将异步触发。

您自己调用的回调是常规函数调用,它们总是同步的

某些本机API(如AJAX、geolocation、Node.js磁盘或网络API)是异步的,稍后将在事件循环中执行回调


如果从异步回调中同步调用回调,它也将以异步结束。

要创建自己的异步函数,必须使用解释器提供的其他异步函数

例如,这段代码定义了一个异步函数“addKeyHandler”。但这仅仅是因为JS引擎异步调用document.onKey。JavaScript引擎能够提供异步功能,因为操作系统提供了这样的功能,然后JS使用这些功能。操作系统反过来只能提供异步功能,因为硬件提供了异步功能(称为硬件中断)

但是,如果操作系统和硬件没有提供任何异步函数,那么仍然可以编写JS解释器。但它必须使用一个无限循环,并在每次迭代中检查是否发生任何事件,然后调用相应的回调。这意味着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));
});
简单地接受回调并不能使函数异步。有许多函数示例采用函数参数但不是异步的,例如,
Array
forEach

要使函数异步,它需要执行异步操作。引入异步性的方法可以是

  • 计时器功能
    setTimeout
    setInterval
  • 特殊功能
    nextTick
    setImmediate
  • 执行I/O(侦听网络、查询数据库、读取或写入资源)
  • 订阅活动

根据文章

给出了一个简单的答案:

除非你面对的是承诺,