• nodejs中事件循环中的执行顺序


    nodejs 事件循环是一个典型的生产者/消费者模型,异步 I/O、网络请求等是事件的生产者,源源不断为 Node 提供不同类型的事件,这些事件被传递到对应的观察者那里,事件循环则从观察者那里取出事件并处理。

    事件循环、观察者、请求对象、I/O 线程池共同构成了 Node 异步 I/O 模型的基本要素。

    Node 异步 I/O 几个关键词:单线程、事件循环、观察者、I/O 线程池,JavaScript 是单线程,node自身是多线程,只是 I/O 线程使用的 CPU 较少。除了用户代码无法并行执行外,所有的 I/O(磁盘 I/O 和网络 I/O 等)是可以并行起来的。

    node 中还存在一些与 I/O 无关的异步 API,setTimeout()、setInteval()、setImmediate()、process.nextTick()

    process.nextTick()=> idle 观察者

    setImmediate() => check 观察者

    事件循环对观察者的检查有先后顺序,idle观察者先于 I/O 观察者,I/O 观察者先于 check 观察者。

    const fs = require("fs");
    const path = require("path");
    
    const wait = () =>
        new Promise((resolove, reject) => {
            setTimeout(resolove(true), 3);
        });
    fs.readFile(
        path.resolve(__dirname, "./limit.js"),
        "utf-8",
        async (err, data) => {
            console.log("读取的文件内容1");
        }
    );
    fs.readFile(
        path.resolve(__dirname, "./limit.js"),
        "utf-8",
        async (err, data) => {
            console.log("读取的文件内容2");
            await wait();
            console.log("读取文件内容2,等待3 秒后输出");
            process.nextTick(() => {
                console.log("读取文件内容2,等待3 秒后执行 process.nextTick");
            });
        }
    );
    
    console.log("start");
    
    setTimeout(function () {
        console.log("setTimeout-1");
        process.nextTick(function () {
            console.log("setTimeout-1-process.nextTick");
        });
        new Promise(function (resolve) {
            console.log("setTimeout-1-Promise");
            resolve();
        }).then(function () {
            console.log("setTimeout-1-Promise-then");
        });
    });
    setImmediate(() => {
        console.log("setImmediate-1");
        process.nextTick(function () {
            console.log("setImmediate-1-process.nextTick-1");
        });
    });
    setImmediate(() => {
        console.log("setImmediate-2");
    });
    process.nextTick(function () {
        console.log("process.nextTick-1");
    });
    process.nextTick(function () {
        console.log("process.nextTick-2");
    });
    new Promise(function (resolve) {
        console.log("Promise-1");
        resolve();
    }).then(function () {
        console.log("Promise-1-then");
    });
    
    setTimeout(function () {
        console.log("setTimeout-2");
        process.nextTick(function () {
            console.log("setTimeout-2-process.nextTick");
        });
        new Promise(function (resolve) {
            console.log("setTimeout-2-Promise");
            resolve();
        }).then(function () {
            console.log("setTimeout-2-Promise-then");
        });
    });
    // 执行结果
    // start
    // Promise-1
    
    // 在每轮循环中,会将 process.nextTick 全部执行完,优先级> promise.then
    // process.nextTick-1
    // process.nextTick-2
    // Promise-1-then
    
    // setTimeout timer 优先级> setImmediate check 观察者
    // setTimeout-1
    // setTimeout-1-Promise
    // setTimeout-1-process.nextTick
    // setTimeout-1-Promise-then
    
    // setTimeout-2
    // setTimeout-2-Promise
    // setTimeout-2-process.nextTick
    // setTimeout-2-Promise-then
    
    // 一次循环只执行一个 setImmediate
    // setImmediate-1
    // setImmediate-1-process.nextTick-1
    // setImmediate-2
    
    // 读取的文件内容1
    // 读取的文件内容2
    // 读取文件内容2,等待3 秒后输出
    // 读取文件内容2,等待3 秒后执行 process.nextTick
  • 相关阅读:
    深入理解javascript中的立即执行函数(function(){…})()
    多行文本溢出省略号显示
    JS学习思路
    canvas画圆
    软件需求与软件评估
    parawork功能使用说明
    ”0元中标的商业逻辑“ -- 如何更好防范项目风险(北京软件造价评估技术创新联盟:李培圣)
    parawork平台介绍
    基准化的软件绩效和成本度量
    jQuery对表格的操作及其他应用
  • 原文地址:https://www.cnblogs.com/beileixinqing/p/16895513.html
Copyright © 2020-2023  润新知