JS 异步 从零讲(大白话 + 真实场景 + 可运行案例)

按顺序:回调函数 → Promise → async/await,工作最常用,直接上手。

  1. 回调函数(最原始,缺点:回调地狱)

  2. Promise(解决回调地狱,链式调用)

    new Promise((resolve, reject) => {
    //异步操作
    //成功 resolve(数据)
    // 失败 reject(错误)
    })
    .then((res) => {
    //成功处理
    })
    .catch((err) => {
    //失败处理
    });

真实场景 封装定时器异步

复制代码
 function fn(msg, delay) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(msg);
          }, delay);
        });
      }

链式调用

复制代码
    fn("第一步", "1000")
        .then((res) => {
          console.log(res);
          return fn("第二步", 1000);
        })
        .then((res) => {
          console.log(res);
          return fn("第三步", 1000);
        })
        .then((res) => console.log(res));

常用静态方法

Promise.all(p1,p2,p3):全部成功才成功(并行请求)

Promise.race(p1,p2):谁先完成取谁

并行 2 个接口,同时发请求

复制代码
   Promise.all([fn("A", 1000), fn("B", 2000)]).then((res) => {
        console.log(res, "Promise.all");
      });
  1. async /await(终极写法,最舒服,项目必用)

async function 函数名(){

const 结果 = await Promise对象;

}

上面的定时器 用async/await 重写

复制代码
 function fnawait(msg, delay) {
        return new Promise((resolve, reject) => {
          setTimeout(() => resolve(msg), delay);
        });
      }
      async function run() {
        const r1 = await fnawait("1", 1000);
        console.log(r1);
        const r2 = await fnawait("2", 1000);
        console.log(r2);
        const r3 = await fnawait("3", 1000);
        console.log(r3);
      }
      run();

捕获错误(try/catch)

复制代码
  async function runDetails() {
        try {
          const res = await fn("第一步", 1000);
          console.log(res);
        } catch (err) {
          console.log("出错了", err);
        }
      }
      runDetails();

一句话总结:

1.回调:嵌套地狱,不用

2.Promise:链式,解决嵌套

3.async/await 最简

完整代码:

复制代码
<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>练习</title>
  </head>
  <body>
    <div id="content"></div>
    <script>
      console.log("--- JS 异步 从零讲(大白话 + 真实场景 + 可运行案例) ---");
      //按顺序:回调函数 → Promise → async/await,工作最常用,直接上手。
      //1. 回调函数(最原始,缺点:回调地狱)
      // 2. Promise(解决回调地狱,链式调用)
      new Promise((resolve, reject) => {
        //异步操作
        //成功 resolve(数据)
        // 失败 reject(错误)
      })
        .then((res) => {
          //成功处理
        })
        .catch((err) => {
          //失败处理
        });
      //真实场景 封装定时器异步
      function fn(msg, delay) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(msg);
          }, delay);
        });
      }
      //   链式调用
      fn("第一步", "1000")
        .then((res) => {
          console.log(res);
          return fn("第二步", 1000);
        })
        .then((res) => {
          console.log(res);
          return fn("第三步", 1000);
        })
        .then((res) => console.log(res));
      // 常用静态方法
      // Promise.all([p1,p2,p3]):全部成功才成功(并行请求)
      // Promise.race([p1,p2]):谁先完成取谁
      // 并行 2 个接口,同时发请求
      Promise.all([fn("A", 1000), fn("B", 2000)]).then((res) => {
        console.log(res, "Promise.all");
      });
      //   3. async /await(终极写法,最舒服,项目必用)
      // async function 函数名(){
      //     const 结果 = await Promise对象;
      // }
      //   上面的定时器 用async/await 重写
      function fnawait(msg, delay) {
        return new Promise((resolve, reject) => {
          setTimeout(() => resolve(msg), delay);
        });
      }
      async function run() {
        const r1 = await fnawait("1", 1000);
        console.log(r1);
        const r2 = await fnawait("2", 1000);
        console.log(r2);
        const r3 = await fnawait("3", 1000);
        console.log(r3);
      }
      run();
      //   捕获错误(try/catch)
      async function runDetails() {
        try {
          const res = await fn("第一步", 1000);
          console.log(res);
        } catch (err) {
          console.log("出错了", err);
        }
      }
      runDetails();
    //   一句话总结:
    //1.回调:嵌套地狱,不用
    //2.Promise:链式,解决嵌套
    //3.async/await 最简
    </script>
  </body>
</html>
相关推荐
传人once10 小时前
页面中心圆圈放大效果如何写
开发语言·javascript·ecmascript
用户0333074139511 小时前
TypeScript using 与 AsyncDisposableStack:在真实服务端代码中协调多资源清理
前端
web3d52011 小时前
Vue3 地图白屏排查清单:容器、弹窗与 ol-viewport 重复创建
vue.js·gis
daisychey11 小时前
用 Playwright 做多平台内容分发,我踩过的 8 个坑
前端
IT_陈寒12 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端
大龄秃头程序员12 小时前
iOS冷启动监控Demo
前端
光影少年12 小时前
为什么 JavaScript 中 0.1 + 0.2 !== 0.3,如何让其相等?
前端·javascript·算法
掘金酱13 小时前
[稀土掘金 × 火山引擎] AI用量周榜冲刺赛|获奖名单公示
前端·人工智能·后端
泡泡oO13 小时前
“如果你还在用Superpowers,那我不要和你说话”
前端·后端·全栈
维克兜率天13 小时前
趋势过滤:避免被“假突破“反复打脸
前端