434 Promise,async,await

我只是一个虾纸丫 提交于 2020-04-04 17:57:26
  1. Promise 是 es6 提出来的一个非常重要的一个语法

  2. Promise 是一种处理异步的解决方案
    通过同步编写代码的方式,处理异步的一种解决方案

  3. 以前 : 处理异步 是怎么处理的 ? 回调

这种回调处理异步 可以的, 简单的情况下 使用 回调处理还凑活, 但是异步请求次数多, 复杂的话, 回调地狱

缺点 : 
1. 代码不优雅 
2. 结构不清晰  
3. 处理起来不方便.....
setTimeout( ()=> {},1000)

$.ajax({
  url : '..',
  data : {},
  success : res => {
  }
})

// 顺序
// 第一次发送请求
$.ajax({
  url : '..',
  data : {},
  success : res => {

    // 第二次发送请求
    $.ajax({
      url : '..',
      data : {},
      success : res => {

         // 第三次发送请求
         $.ajax({
          url : '..',
          data : {},
          success : res => {

          }
        })

      }
    })

  }
})
  1. 解决方式 : Promise
Promise.then( res => {
         //第一次发送请求
        })
        .then(res => {
          //第二次发送请求
        })
        .then(res => {
          // 第三次发送请求
        })

02-Promise的基本使用.js

 /**
  * 1. Promise是一个构造函数 
  * 2. () 参数里是一个回调函数 
  *   resolve : fn  => 异步操作成功, 调用resolve
  *   reject :  fn  => 异步操作失败, 调用 reject
  * 3. Promise里面放一个异步操作
  */


 /** 
  * 1. p 是 Promise 类型 
  * 2. axios.get() 都是promise类型
  * 3. promise的类型的实例,都可以点then
  * axios.get().then()
  * axios.post().then()
  *  p.then()
  *  XXX.then()
  */


 //  自己封装的 promise
 const p = new Promise((resolve, reject) => {
     setTimeout(() => {
         // console.log('异步操作开始了');

         // 如果异步操作成功 => 调用 resolve  => 走 实例对象的then => 传参数
         // resolve('成功的信息')

         // 如果异步操作失败 => 调用 reject  => 走 实例对象的catch => 传参数
         reject('这是一条错误信息')
     }, 0);

 })

 // 供别人调用的
 p.then(res => {
         console.log('then被调用了: ', res);
     })
     .catch(err => {
         console.log('catch 被调用了: ', err);
     })

03-Promise的注意点.js

/**
 *  自定义封装Promise
 * 1. Promise 构造函数
 * 2. () 回调函数
 *   resolve
 *   reject
 * 3. Promise里面放一个异步操作
 */

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        // 成功
        resolve('这是成功消息')
            // 失败
            // reject()
    }, 0)
})

p.then(res1 => {
    console.log('then 被调用了1:', res1) // 这是成功消息
}).then(res2 => {
    console.log('then 被调用了2: ', res2); // undefined
}).then(res3 => {
    console.log('then 被调用了3', res3); // undefined
})

// 注意点1 : p .then().then().then().then() .catch()...是链式编程 每次调用返回的都是 promise类型 

// 注意点2 : 
//  第一个then, 拿到的是promise类型的p中resolve返回给我们的值,
//  第二个then, 拿到的确实undefined, 因为 p.then() => 新的promise类型实例,resolve()是空的
//  后面的.then() 出来的都是新的promise实例

//   .catch(err => {
//   console.log('catch 被调用了')
// })


// 链式编程
// p.then().catch()

04-使用Promise封装一个异步读取 文件.js

//1. 引入 模块
const fs = require('fs')

//3. 使用 Promise 封装起来
const p = new Promise((resolve,reject) => { 

  fs.readFile('./a1.txt', 'utf-8', (err, data) => { 
    if (err) {
      return reject('读取失败'); 
    }
    // console.log(data)
    resolve(data)
  })
})

p.then(res => { 
  console.log('then : ',res);
})
  .catch(err => { 
    console.log('catch:',err);
    
  })


//2 异步读取 文件
// fs.readFile('./a.txt', 'utf-8', (err, data) => {
//   if (err) {
//     return console.log('读取失败')
//   }

//   console.log(data)
// })


05-使用Promise封装一个异步读取多个文件.js

// 1. 引入 模块
const fs = require('fs')

// 2. 封装promise
function ml_readF(filepath) {
    const p = new Promise((resolve, reject) => {
        fs.readFile(filepath, 'utf-8', (err, data) => {
            if (err) {
                return reject('读取失败')
            }

            resolve(data)
        })
    })

    return p
}

// 3. 使用
// ml_readF('./a.txt') 读取 a.txt 的 promise
ml_readF('./a.txt')
    .then(res1 => {
        console.log('then :', res1)

        return ml_readF('./b.txt')
    })
    .then(res2 => {
        console.log('then : ', res2)
        return ml_readF('./c.txt')
    })
    .then(res3 => {
        console.log('then :', res3)
    })

// p.then(res1 => {
//   console.log('then :',res1);
// })

06-async和await.js

/**
 * async 和 await 是 es8 提出来的一个语法
 * 想`同步编写代码`的方式`处理异步`, 处理的更加彻底
 
 * async: 修饰一个内部有异步操作的函数,  格式:  async + 函数
 * await: 等待一个异步操作的结果,        格式:  await 异步操作(promise类型)
 */


// 1. 引入 模块
const fs = require('fs')

// 2. 封装promise
function ml_readF(filepath) {
    const p = new Promise((resolve, reject) => {
        fs.readFile(filepath, 'utf-8', (err, data) => {
            if (err) {
                return reject('读取失败')
            }
            resolve(data)
        })
    })

    return p
}

//3. 需求: 先后读取 a.b.c (都是异步的)

// ml_readF('./a.txt').then(res => {
//   console.log(res);
// })

// async: 修饰一个内部有(await)异步操作的函数 【不能用箭头函数。】
async function fn() {
    // 格式 : await + promise类型 
    // 结果 : let a = ?  a 就是以前 then(res => res的结果 )
    let a = await ml_readF('./a.txt')
    console.log(a) // aaaa

    let b = await ml_readF('./b.txt')
    console.log(b) // 大傻春

    let c = await ml_readF('./c.txt')
    console.log(c) // 小马哥
}

fn()

07-async和await的注意点.js

/**
 * async 修饰一个内部有异步操作的函数   async + 函数
 * await 等待一个异步操作的结果       let res = await 异步操作(promise类型)
 */

// 1. 引入 模块
const fs = require('fs')

// 2. 封装promise
function ml_readF(filepath) {
    const p = new Promise((resolve, reject) => {
        fs.readFile(filepath, 'utf-8', (err, data) => {
            if (err) {
                return reject('读取失败')
            }

            resolve(data)
        })
    })
    return p
}

/**
 * 注意点1 : async 和 await 成对出现
 * 注意点2 : async 添加的函数,一定是await `最近`的函数
 * 注意点3 : async 和 await 如果要处理异常,配合使用 try...catch
 */

async function fn1() {
    try {
        // 读取 a 
        let a = await ml_readF('./a1.txt')
        console.log(a)
    } catch (error) { // 捕获 异常
        console.log('读取a失败了'); // 读取a失败了
    }

    // 读取 b
    let b = await ml_readF('./b.txt')
    console.log(b); // 大傻

    // 读取 c 
    let c = await ml_readF('./c.txt')
    console.log(c); // 小马哥 
}

fn1()

08-尝试改造axios.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <script src="./node_modules/axios/dist/axios.js"></script>
    <script>
        /*  */
        /* axios
            .get(
                'http://localhost:8888/api/private/v1/login?username=admin&password=123456'
            )
            .then(res => {
                console.log(res)
            })

        let p = axios
            .get(
                'http://localhost:8888/api/private/v1/login?username=admin&password=123456'
            )
        console.log(p); // Promise对象 */


        // 既然 axios.get() 就是一个promise类型 就可以使用 async 和 await 改造

        // async 修饰一个函数
        // await  等待一个结果

        async function fn() {
            let res = await axios.get('http://localhost:8888/api/private/v1/login?username=admin&password=123456')
            console.log(res)
        }
        fn()
    </script>
</body>

</html>

09-Promise的其他两个方法的使用.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- 
      需求1 : 想让三个异步请求都完成了, 再执行我们的操作
      Promise.all([n个异步请求]) 

      需求2 : 只要其中的一个完成了,就可以执行我的操作 (竞赛)
      Promise.race() 
     -->

    <!-- 
         json-server的url规则:http://localhost:3000/ + key
         data.json的数据:
         {
            "one": [11, 12, 13, 14],
            "two": [21, 22, 23, 24],
            "three": [31, 32, 33, 34]
        }
      -->

    <script src="./node_modules/axios/dist/axios.js"></script>
    <script>
        // Promise.race([
        //     axios.get('http://localhost:3000/one'),
        //     axios.get('http://localhost:3000/two'),
        //     axios.get('http://localhost:3000/three')
        // ]).then(res => {
        //     console.log('res : ', res)
        //     console.log('开始我们的操作了')
        // })

        Promise.all([
            axios.get('http://localhost:3000/one'),
            axios.get('http://localhost:3000/two'),
            axios.get('http://localhost:3000/three')
        ]).then(res => {
            console.log('res : ', res)
            console.log('开始我们的操作了')
        })
    </script>
</body>

</html>


10-Promise的三个状态.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /**
       * 三个状态 :
       * pending  等待/进行中
       * resolved  操作成功
       * rejected  操作失败
       */
      const p = new Promise((resolve, reject) => {
        setTimeout(() => {
          reject()
        }, 0)
      })

      console.log(p)
    </script>
  </body>
</html>


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!