处理异步事件的三种方式

在开发中,异步事件是项目必然需要处理的一个环节,也因为前端框架的崛起,通过框架实现的 SPA 已是快速开发的基本了,异步获取数据也就成了不可或缺的一环。

同步?异步?

这两个名次从字面上很容易让人反过来理解

       同步:指一件一件做事;

       异步:很多事情同时处理;

             类似过桥.同步是独木桥只能一个一个的过,异步是有多座桥,可同时过。

那么在 js 中处理异步事件的方法是什么呢?

      1.回调函数

              最熟悉的就是回调函数了。例如网页与用户进行互动时,就需要接收一个回调函数;如setTimeout,也都能通过传递回调函数在用户要求的时机去触发。先看例子:

function timeoutCallback(() {
  console.log('start')
  setTimeout(() => {
    console.log('callback')
  }, 1000)
  console.log('done')
}
timeoutCallback()

             在 setTimeout 被执行后,当过了指定的时间间隔之后,回调函数会被放到队列的末端,再等待事件处理它。

             回调函数虽然在开发中十分常见,但也有许多难以避免的问题。例如最著名的“回调地狱”。

    2.Promise

            在 ES6 之后出现了 Promise,拯救了身陷在地狱的我们。

function matexiaPromise() {
  return new Promise(resolve => {
    console.log('promise')
    resolve()
  })
}
matexiaPromise()
  .then(() => console.log('then 1'))
  .then(() => setTimeout(() => console.log('setTimeout'), 0))
  .then(() => console.log('then 2'))
  .catch((err) => console.log('catch:', err))

           Promise 是通过微任务队列来驱动它的;微任务队列的触发时机是在栈被清空时,JavaScript 引擎会先确认微任务队列有没有东西,有的话就优先执行,直到清空后才从队列拿出新任务到栈上。(在HTML 5 的Web API 标准 中,Event Loop 新增了微任务队列)

    上述例子setTimeout就能很好的理解微任务与一般任务的差别,同时通过.catch语法来处理异步错误

    3.async/await

          从 Promise 问世之后,异步代码从回调地狱逐渐变成了优雅的函数式管道处理,但对于不熟悉的开发者来说,只不过是从回调地狱变成了 Promise 地狱。

          在 ES8 中规范了新的 async await,虽然只是 Promise 和 Generator Function组合在一起的语法糖,但通过 async await便可以将异步事件用同步语法来处理。

function matexiawait(time) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('wait:', time)
      resolve(time)
    }, time)
  })
}
await matexiawait(1000, () => console.log('bar'))
console.log('foo')

          通过把 setTimeout包装成 Promise,再用 await关键字调用,可以看到结果会是同步执行的先出现 bar,再出现 foo,也就是开头提到的将异步事件写成同步处理。

          在使用async/await时,由于await关键字只能在 async function 中执行,使用时务必要记得要同时使用。

          另外在用循环处理异步事件时,需要注意在 ES6 之后提供的很多 Array 方法都不支持async/await语法

 关注前端公众号(前端中心),获取更多前端技术,共同成长.

处理异步事件的三种方式_第1张图片

 

你可能感兴趣的:(前端,js,javascript,javascript,es6,前端,jquery)