同步和异步有何不同

单线程和异步

  1. JS是单线程语言,只能同时做—件事。
  2. 浏览器和nodejs已支持JS启动进程,如Web Worker
  3. JS和DOM渲染共用同一个线程,因为JS可修改DOM结构
  4. 遇到等待(网络请求,定时任务)不能卡住
  5. 需要异步
  6. 回调callback函数形式

    异步和同步

    image.png

js是单线程语言,同步会阻塞代码的运行,异步不会阻塞代码的运行。比如ajax请求如果使用同步的写法则会让进程卡掉。

异步的应用场景有哪些

网络请求,如ajax、图片加载

image.png

  1. 打印start
  2. 执行网络请求,得到data1
  3. 打印end
  4. 网络请求结束,得到end,执行回调函数打印data1

image.png

  1. 打印start
  2. 定义img
  3. 定义onload回调函数
  4. 给img.src赋值,触发图片加载
  5. 打印end
  6. 图片加载完成,触发onload,打印loaded

    定时任务,如setTimeout、setInterval

image.png

promise的基本使用(用来解决callback hell)

callback hell

image.png

  1. 获取第一份数据
  2. 根据第一份数据获取第二份数据
  3. 根据第二份数据获取第三份数据
  4. ….

为了解决异步回调地狱,产生了Promise

Promise

Promise的语法

image.png
resolve触发then,reject触发error

Promise的使用

image.png
将异步回调地狱的嵌套形式变成了串联的形式

面试题

同步和异步的区别是什么?

基于JS是单线程的语言,异步不会阻塞代码的执行,同步会阻塞代码的执行。

手写Promise加载一张图片

  1. function loadImg(src) {
  2. const p = new Promise(
  3. (resolve, reject) => {
  4. const img = document.createElement('img')
  5. img.onload = () => {
  6. resolve(img)
  7. }
  8. img.onerror = () => {
  9. const err = new Error(`图片加载失败 ${src}`)
  10. reject(err)
  11. }
  12. img.src = src //调用img.src立刻触发加载图片操作
  13. }
  14. )
  15. return p
  16. }
  17. // const url = 'https://img.mukewang.com/5a9fc8070001a82402060220-140-140.jpg'
  18. // loadImg(url).then(img => {
  19. // console.log(img.width)
  20. // return img
  21. // }).then(img => {
  22. // console.log(img.height)
  23. // }).catch(ex => console.error(ex))
  24. const url1 = 'https://img.mukewang.com/5a9fc8070001a82402060220-140-140.jpg'
  25. const url2 = 'https://img3.mukewang.com/5a9fc8070001a82402060220-100-100.jpg'
  26. //下面代码是多个图片一起加载
  27. loadImg(url1).then(img1 => {
  28. console.log(img1.width)
  29. return img1 // 普通对象
  30. }).then(img1 => {
  31. console.log(img1.height)
  32. return loadImg(url2) // promise 实例
  33. }).then(img2 => {
  34. console.log(img2.width)
  35. return img2
  36. }).then(img2 => {
  37. console.log(img2.height)
  38. }).catch(ex => console.error(ex))

非常重要!
如果then中return的是一个普通对象,下一个then函数中的参数就会接收到
如果then中return—个Promise实例的话,下一个then函数接收到的参数就是新Promise的resolve参数

前端异步的使用场景有哪些?

见上

setTimeout场景题

image.png