美文网首页
41.异步代码解决方案

41.异步代码解决方案

作者: 静昕妈妈芦培培 | 来源:发表于2021-11-25 08:28 被阅读0次

    需求:

    • 第一次请求:url: 'aaa',
    • 第二次请求:url: 第一次请求结果拼接上'bbb',
    • 第三次请求:url: 第二次请求结果拼接上'ccc',

    方案一

    //请求封装
    function requestData(url, successCallback, failureCallback) {
      //模拟异步请求
      setTimeout(() => {
        if (typeof url === "string") {
          successCallback(url);
        } else {
          failureCallback("参数url必须是字符串类型");
        }
      }, 3000);
    }
    
    //第一次请求
    requestData(
      "aaa",
      (res1) => {
        //第二次请求
        requestData(
          res1 + "bbb",
          (res2) => {
            //第三次请求
            requestData(
              res2 + "ccc",
              (res3) => {
                console.log("最终请求结果为", res3);
              },
              (err) => {
                console.log(err);
              }
            );
          },
          (err) => {
            console.log(err);
          }
        );
      },
      (err) => {
        console.log(err);
      }
    );
    
    //执行结果:最终请求结果为 aaabbbccc
    
    

    方案二:promise

    //请求封装
    function requestData(url) {
      return new Promise((resolve, reject) => {
        //模拟异步请求
        setTimeout(() => {
          if (typeof url === "string") {
            resolve(url);
          } else {
            reject("参数url必须是字符串类型");
          }
        }, 3000);
      });
    }
    
    //方式一:
    //第一次请求
    requestData("aaa").then((res1) => {
      //第二次请求
      requestData(res1 + "bbb").then((res2) => {
        //第三次请求
        requestData(res2 + "ccc").then((res3) => {
          console.log("最终请求结果为", res3);
        });
      });
    });
    //执行结果:最终请求结果为 aaabbbccc
    
    //方式二:
    requestData("aaa")
      .then((res1) => {
        //第二次请求
        return requestData(res1 + "bbb");
      })
      .then((res2) => {
        //第三次请求
        return requestData(res2 + "ccc");
      })
      .then((res3) => {
        console.log("最终请求结果为", res3);
      });
    
    //执行结果:最终请求结果为 aaabbbccc
    
    

    方案三:promise + generator

    //请求封装
    function requestData(url) {
      return new Promise((resolve, reject) => {
        //模拟异步请求
        setTimeout(() => {
          if (typeof url === "string") {
            resolve(url);
          } else {
            reject("参数url必须是字符串类型");
          }
        }, 3000);
      });
    }
    
    
    //创建生成器函数
    function* getData() {
      const res1 = yield requestData("aaa");
      const res2 = yield requestData(res1 + "bbb");
      const res3 = yield requestData(res2 + "ccc");
      console.log("执行结果:最终请求结果为", res3);
    }
    
    //手动执行生成器函数
    const generator = getData();
    
    //第一次请求
    generator
      .next().value.then((res1) => {
        // 第二次请求
        return generator.next(res1).value;
      })
      .then((res2) => {
        // 第三次请求
        return generator.next(res2).value;
      })
      .then((res3) => {
        generator.next(res3);
      });
    
    // 执行结果:最终请求结果为 aaabbbccc
    

    方案四:promise + generator

    封装一个自动执行生成器函数

    //请求封装
    function requestData(url) {
      return new Promise((resolve, reject) => {
        //模拟异步请求
        setTimeout(() => {
          if (typeof url === "string") {
            resolve(url);
          } else {
            reject("参数url必须是字符串类型");
          }
        }, 3000);
      });
    }
    
    
    //创建生成器函数
    function* getData() {
      const res1 = yield requestData("aaa");
      const res2 = yield requestData(res1 + "bbb");
      const res3 = yield requestData(res2 + "ccc");
      console.log("执行结果:最终请求结果为", res3);
    }
    
    //封装一个自动执行生成器函数
    function execGenerator(generatorFn) {
      const generator = generatorFn();
    
      function exec(res) {
        const result = generator.next(res);
        if (result.done) return result.value;
        result.value.then((res) => {
          exec(res);
        });
      }
      exec();
    }
    
    execGenerator(getData);
    
    

    方案五:借助co模块

    npm install co
    
    const co = require('co')
    
    //请求封装
    function requestData(url) {
      return new Promise((resolve, reject) => {
        //模拟异步请求
        setTimeout(() => {
          if (typeof url === "string") {
            resolve(url);
          } else {
            reject("参数url必须是字符串类型");
          }
        }, 3000);
      });
    }
    
    
    
    //创建生成器函数
    function* getData() {
      const res1 = yield requestData("aaa");
      const res2 = yield requestData(res1 + "bbb");
      const res3 = yield requestData(res2 + "ccc");
      console.log("执行结果:最终请求结果为", res3);
    }
    
    co(getData)
    //执行结果:最终请求结果为 aaabbbccc
    

    方案六:async/await

    const co = require("co");
    
    //请求封装
    function requestData(url) {
      return new Promise((resolve, reject) => {
        //模拟异步请求
        setTimeout(() => {
          if (typeof url === "string") {
            resolve(url);
          } else {
            reject("参数url必须是字符串类型");
          }
        }, 3000);
      });
    }
    
    
    
    //创建生成器函数
    async function getData() {
      const res1 = await requestData("aaa");
      const res2 = await requestData(res1 + "bbb");
      const res3 = await requestData(res2 + "ccc");
      console.log("执行结果:最终请求结果为", res3);
    }
    
    getData();
    //执行结果:最终请求结果为 aaabbbccc
    
    

    非常感谢王红元老师的深入JavaScript高级语法让我学习到很多 JavaScript 的知识

    相关文章

      网友评论

          本文标题:41.异步代码解决方案

          本文链接:https://www.haomeiwen.com/subject/pzgntrtx.html