一尘不染

所有的JavaScript回调都是异步的吗?如果没有,我怎么知道是哪个?

javascript

我很好奇所有的JavaScript回调是异步的,还是仅在某些情况下才是异步的。另外,我确定是什么使浏览器和Node.js的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);

但是,例如,我知道jQuery的AJAX函数是真正异步的(没有考虑到现在可用的承诺)。是什么使jQuery的AJAX异步?它涉及XHR请求是否很简单,并且在浏览器中,所有XHR请求都是异步的?

对于nodejs环境,我有同样的问题。如果节点中的某些内容涉及文件I /
O,process.nextTick,setTimeout或setInterval,那么它是否只能是异步的?为什么当我使用mongodb /
mongoose进行数据库调用之类的操作时,它是异步的?幕后到底是怎么回事?

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


阅读 232

收藏
2020-04-25

共1个答案

一尘不染

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

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

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

但是,例如,我知道jQuery的AJAX函数确实是异步的…

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

是什么使jQuery的AJAX异步?

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

还是有某种方法可以使自己的功能真正异步而无需利用环境的特定功能…

直到最近,还没有。在第5版规范中,JavaScript 语言
基本上对线程和异步的整个概念保持沉默。只是当您进入环境时,它才会出现。使某事物异步的唯一方法是使用主机提供的功能,例如nextTickNodeJS或setTimeout浏览器上的(或(异步完成的各种操作中的任何一种))。

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

2020-04-25