什么是异步?

说说你的理解,什么是异步。
由于各个语言处理异步的机制有差异,我们这里只说 JS 中的异步。

怎么样的代码是异步代码?

我们先不深入异步概念,先从「表象」来看看怎么样的代码是异步代码:

异步代码的书写顺序与执行顺序不同。(这并不是异步的定义。另外「书写顺序与执行顺序不同的代码」不一定是异步代码)

console.log(1)
setTimeout(function(){
  console.log(2)
},0)
console.log(3)

上面代码的书写顺序是 1 -> 2 -> 3;

但是执行顺序是 1 -> 3 -> 2。

中间的 console.log(2) 就是异步执行的。

你现在知道了「代码的书写顺序和执行顺序居然可以不同!」

什么是异步?

同步:一定要等任务执行完了,得到结果,才执行下一个任务。

function taskSync = function(){
  return '同步任务的返回值'
}

var result = taskSync() // 那么 result 就是同步任务的结果
otherTask()             // 然后执行下一个任务

异步:不等任务执行完,直接执行下一个任务。

function taskAsync = function(){
  var result = setTimeout(function(){
    console.log('异步任务的结果')
  }, 3000)
  return result
}

var result = taskAsync() // result 不是异步任务的结果,而是一个 timer id
otherTask()              // 立即执行其他任务,不等异步任务结束

聪明的你可能会发现,我们拿到的 result 不是异步执行的结果,而是一个 timer id,那么要怎么拿到异步任务的结果呢?

用回调。

改下代码如下:

function taskAsync = function(callback){
  var result = setTimeout(function(){
    callback('异步任务的结果')
  }, 3000)
  return result
}

taskAsync(function callback(result){
  console.log(result) // 三秒钟后,这个 callback 函数会被执行
})
otherTask()              // 立即执行其他任务,不等异步任务结束

所以「回调」经常用于获取「异步任务」的结果。

什么情况下需要用到异步?

现在有三个函数,taskA()、taskB() 和 taskC(),三个任务互不影响。
taskA 和 taskC 执行得很快,但是 taskB 执行需要 10 秒钟。

// 同步的写法
function taskB(){
  var response = $.ajax({
    url:"/data.json",
    async: false // 注意这里 async 为 false,表示是同步
  })
  return response // 十秒钟后,返回 response
}

taskA()
taskB()
taskC()

taskC 一定要等 taskB 执行完了才能执行,这就是同步。

执行顺序为:

A -> B -> AJAX 请求 -> C ---------------------------

现在换成异步:

// 异步的写法
function taskB(){
  var result = $.ajax({
    url:"/data.json",
    async: true // 异步
  })
  return result // 一定要注意,现在的 result 不是上面的 response
}
taskA()
taskB()
taskC()

这样写之后,执行顺序就是

A -> B -> C ---------------------------------------
       -> AJAX 请求 --------------------------------

就是说 AJAX 请求和任务C 同时执行。

但是请注意执行的主体。AJAX 请求是由浏览器的网络请求模块执行的,taskC 是由 JS 引擎执行的。

综上,如果几个任务互相独立,其中一个执行时间较长,那么一般就用异步地方式做这件事。

JS 引擎不能同时做两件事

有些人说异步是同时做两件事,但其实 JS 引擎不会这样。

以 setTimeout 为例,setTimeout 里面的代码一定会在当前环境中的任务执行完了「之后」才执行。

异步意味着不等待任务结束,并没有强制要求两个任务「同时」进行。

但是 AJAX 请求是可以与 JS 代码同时进行的,因为这个请求不是由 JS 引擎负责,而是由浏览器网络模块负责。

以上,就是异步的简介。

网络上对异步的解释很多,这里只是我的一己之见,如有疏漏,还望见谅。

作者:方应杭, 想学前端?进群

3 thoughts on “什么是异步?”

  1. Terrific article! That is the kind of info that should be shared across the web. Shame on Google for not positioning this post upper! Come on over and talk over with my web site . Thanks =)|

  2. I believe this is among the so much important information for me. And i’m glad reading your article. But should commentary on some general things, The site taste is wonderful, the articles is really nice : D. Good job, cheers|

  3. After looking into a handful of the articles on your website, I truly appreciate your technique of writing a blog. I added it to my bookmark webpage list and will be checking back soon. Take a look at my website as well and tell me your opinion.|

发表评论

电子邮件地址不会被公开。