Promise

基础用法

  1. function roller() {
  2. return new Promise((resolve, reject) => {
  3. setTimeout(() => {
  4. resolve(Math.floor(Math.random() * 6) + 1)
  5. }, 3000);
  6. })
  7. }
  8. roller().then((data) => {
  9. console.log(data)
  10. }, (err) => {
  11. console.log(err)
  12. })

其他API

  • Promise.resolve(result) 制造一个成功(或者失败)
  • Promise.reject(reason) 制造一个失败
  • Promise.all(数组) 等待全部成功,或者有一个失败
  • Promise.race(数组) 等待第一个状态改变
  • Promise.allSettled(数组) 等待全部状态改变,目前处于State4

    应用场景

  • 多次处理一个结果

    • 摇色子.then(v=>v1).then(v1=>v2)
  • 串行
    • 这里有一个悖论:一旦promise出现,那么任务就已经执行了
    • 所以不是promise串行,而是任务串行
    • 解法:把任务放进队列,完成一个再做下一个
  • 并行
    • Promise.all([p1,p2]) 不好用
    • Promise.allSettled 太新,不好兼容

面试题

页面有两个按钮A和B,以及一个输入框,A按钮点击后发送一个请求,返回一个字符串A,B也发送请求,但返回字符串B,返回后会把字符串赋值给输入框。但是A、B发送的两个请求返回时间不同,点击两个按钮的顺序也不一定,B要比A先返回,二最终效果要求是输入框字符的书序是A B。

图解

35.async&await - 图1
点击查看【codepen】

解法

点击查看【codepen】

Async/Await替代Promise的6个理由

Async&Await

  • 常见用法

    1. const fn =async ()=>{
    2. const temp=await makePromise()
    3. return temp + 1
    4. }
  • 有点

无需缩进,就像在写同步代码

封装async

  1. function 摇色子(){
  2. return new Promise((resolve,reject)=>{
  3. setTimeout(()=>{
  4. resolve(Math.floor(Math.random()*6)+1)
  5. },3000)
  6. })
  7. }
  8. async function fn(){
  9. var result=await 摇色子()
  10. console.log(result)
  11. }
  12. fn()
  • 抛出错误

    1. async function 摇色子(){
    2. throw new Error('出问题')
    3. }
    4. async function fn(){
    5. try{
    6. var result = await 摇色子()
    7. console.log(result)
    8. }catch(e){
    9. console.log(e.message)
    10. }
    11. }
    12. fn()

    why need async?

  • 看起来有带点多余,await所在函数就是async,为什么外面还要写async?

    • 一句话:为了兼容旧代码里的普通函数里的await(xxx)
    • 如果在await发布前,有的代码内可能有函数命名为await。发布后,单纯使用await会影响到这些函数。所以要配合外面的async才不会影响以前的await。

      正确的错误处理

      1. const response = await axios.get('_xxx').then(null,errorHandler)
      2. console.log(response)
  • 细节

    • 可以把4xx、5xx等常见错误用拦截器全局处理
    • await只用关心成功,失败全部交给errorHandler
    • errorHandler也可以放在拦截器里
  • 在then中去处理错误,await只接受成功的结果

    1. ajax = function(){
    2. return new Promise((resolve,reject)=>{
    3. reject({
    4. response:{
    5. status:403
    6. }
    7. })
    8. })
    9. }
    10. var error=(e)=>{
    11. console.log(e)
    12. throw e
    13. }
    14. async function fn(){
    15. const response = await ajax().then(null,error)
    16. console.log(response)
    17. }
    18. fn()

    await的传染性

    代码

    1. console.log(1)
    2. await console.log(2)
    3. console.log(3)
  • console.log(3)变异步任务了

  • Promise同样有传染性(同步变异步)
  • 回调 是没有传染性的

    await的应用场景

  • 多次处理一个结果

    • const r1 = await makePromise()
    • const r2 = handleR1(r1)
    • const r3 = handleR2(r2)
  • 串行
    • 天生串行
    • 循环的时候又bug
  • 并行
    • await Promise.all([p1,p2,p3]) 就是并行

await 循环

for

  • 打开控制台,运行结果为 4 2 1
  • 说明 for 循环中的 await 是串行的(后面等前面)

点击查看【codepen】

foreach

  • 打开控制台,运行结果为 1 2 3
  • 说明 forEach 循环中的 await 是并行的(后面不等前面)

点击查看【codepen】

题目


    1. let a = 0
    2. let test = async () => {
    3. a = a + await 10
    4. console.log(a)
    5. }
    6. test();
    7. console.log(++a)
    答案
    1
    10