• 技术文章 >web前端 >js教程

    深入了解Node.js中的异步编程,分享四种解决方案

    青灯夜游青灯夜游2021-09-14 10:15:03转载102
    有异步I/O,必有异步编程!今天来学习Node.js里的异步编程!

    异步编程概述

    曾经的单线程模型在同步I/O的影响下,由于I/O调用缓慢,在应用层面导致CPU与I/O无法重叠进行。为了照顾编程人员的阅读思维习惯,同步I/O盛行了很多年。【推荐学习:《nodejs 教程》】

    1.png

    但是有很大的性能问题!

    Node利用JavaScript及其内部异步库,将异步直接提升到业务层面。Node带来的最大特性莫过于基于事件驱动的非阻塞I/O模型。非阻塞I/O可以使CPU与I/O并不相互依赖等待,让资源得到更好的利用。

    2.png

    异步编程解决方案

    目的:读取package.json 中main 字段对应的文件内容

    Callback

    使用回调函数进行异步I/O的操作

    const fs = require("fs");
    
    fs.readFile("./package.json", { encoding: "utf-8" }, (err, data) => {
      if (err) throw err;
      const { main } = JSON.parse(data);
      fs.readFile(main, { encoding: "utf-8" }, (err, data) => {
        if (err) throw err;
        console.log(data);
      });
    });

    3.png

    问题:如何解决回调地狱?

    Promise

    Promise是一个具有四个状态的有限状态机,其中三个核心状态为Pending(挂起),Fulfilled( 完成)、Rejected(拒绝),以及还有一个未开始状态

    详细内容可以看我之前的博文 Promise初探

    4.png

    使用Promise,实现读取 package.json 中 main 字段对应的文件内容

    const { readFile } = require("fs/promises");
    
    readFile("./package.json", { encoding: "utf-8" })
      .then((res) => {
        return JSON.parse(res);
      })
      .then((data) => {
        return readFile(data.main, { encoding: "utf-8" });
      })
      .then((res) => {
        console.log(res);
      });

    对比之前用Callback的解决方案,可以看出没有嵌套的回调了,通过一系列的链式调用来处理异步操作。

    5.png

    Callback 转为 Promise

    如何将 Callback 转为 Promise 形式?

    可以使用Node自带的工具函数 util.promisify

    可以自己实现一下:

    function promisify(fn, receiver) {
      return (...args) => {
        return new Promise((resolve, reject) => {
          fn.apply(receiver, [
            ...args,
            (err, res) => {
              return err ? reject(err) : resolve(res);
            },
          ]);
        });
      };
    }
    
    const readFilePromise = promisify(fs.readFile, fs);

    await

    await 函数使用 try catch 捕获异常(注意并行处理)

    const { readFile } = require("fs/promises");
    
    const start = async () => {
      const { main } = JSON.parse(
        await readFile("./package.json", { encoding: "utf-8" })
      );
      const data = await readFile(main, { encoding: "utf-8" });
      console.log(data);
    };
    start();

    await的语法写起来就像同步编程一样,这里的操作是串行操作,会一行一行的等待执行。

    6.png

    如果几个任务是可以并行的,这样写就不太好了。这是,我们可以使用Promise.all来操作并行的任务

    这里也会有个小问题,我课后问老师了,这是老师的解答

    7.png

    【问】在异步那块,说到串行和并行,在并行处理那块我有一个疑问。如果并行的场景要求:不管其他任务执行成功还是失败,每个异步任务都要执行完,最后统一处理错误,那在用Promise.all来处理多个异步任务时候,遇到第一个任务执行错误的时候就会返回,如何操作才能让所有任务都执行完成,再统一处理错误呢

    【答】Promise.all 处理多个请求,当所有请求都成功的时候,resolve 一个数组回来,里面是执行结果。如果有一个请求失败就立刻 reject 那个错误来,所以这个地方我们不能使用 Promise.all 来实现。Promise 有一个 allSettled 方法,developer.mozilla.org/en-US/docs/…

    Event

    发布订阅模式,Node.js 内置events 模块

    比如HTTP server on('request') 事件监听

    const EventEmitter = require("events");
    
    class MyEmitter extends EventEmitter {}
    
    const myEmitter = new MyEmitter();
    
    myEmitter.on("event", () => {
      console.log("an event occurred!");
    });
    myEmitter.emit("event");
    
    const http = require("http");
    
    const server = http.createServer((req, res) => {
      res.end("hello!!! this is YK!!!");
    });
    server.on("request", (req, res) => {
      console.log(req.url);
    });
    
    server.listen(3000);

    8.png

    9.png

    原文地址:https://juejin.cn/post/7005509871000895524

    作者:YK菌

    更多编程相关知识,请访问:编程视频!!

    以上就是深入了解Node.js中的异步编程,分享四种解决方案的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金--YK菌,如有侵犯,请联系admin@php.cn删除
    专题推荐:Node.js 异步编程
    上一篇:快速了解Angular中的onPush变更检测策略 下一篇:15个值得收藏的实用JavaScript代码片段(项目必备)
    线上培训班

    相关文章推荐

    • 怎么利用Node.js查看操作系统及其版本号• 浅谈nodejs中怎么对字符串进行Base64编码和解码• 浅谈利用Node.js如何获取WI-FI密码• nodejs和vuejs是啥• 怎么查看nodejs安装路径

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网