同步/异步 及 async/await异步处理->同步化

62 阅读3分钟

一、概念介绍

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。

1.1 同步任务与异步任务

于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

1.2 常见异步任务

异步任务一般有以下三种类型:

1 普通事件,如:click、resize、DOM事件,等等
2 定时器,如:setTimeout、setInterval,等等
3 资源加载,如:load、error,等等

1.3 异步执行的运行机制、事件循环

具体来说,异步执行的运行机制如下。(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。异步任务(回调函数)放入任务队列中,
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。

同步(Promise)>异步(微任务(process.nextTick、Promise.then、Promise.catch、resolve、reject)>宏任务(setTimeout、setInterval、setImmediate))

1.4 图示例

image.png

image.png

二、promise

2.1 介绍

promise是解决异步的方法,本质上是一个构造函数,可以用它实例化一个对象。对象身上有resolve、reject、all,原型上有then、catch方法。promise对象有三种状态:pending(初识状态/进行中)、resolved或fulfilled(成功)、rejected(失败)

2.2 await / async ES7的新规范

await / async这两个命令是成对出现的,如果使用await没有在函数中使用async命令,那就会报错,如果直接使用async没有使用await不会报错,只是返回的函数是个promise,可以,但是没有意义,所以这两个一起使用才会发挥出它们本身重要的作用。

这两个命令怎么用那,还是通过上面的案例,来该着一下then的链式调用代码

async onLoad() {
  let id,res;
  res=await this.getNav();
  id=res.data[0].id;
  res=await this.getArticle(id);
  id=res.data[0].id;
  res=await this.getComment(id);
  console.log(res)
}

可以看到onload是函数,这个函数必须有async命令,在调用函数的部分,前面都加了一个await,这个命令的意思就是等这一行的异步方法执行成功后,将返回的值赋值给res变量,然后才能再走下一行代码,这就是将原来的异步编程改为了同步编程,这就是标题提到的“异步处理,同步化”。