Node core and Node eventLoop

What is the Node

  • Node.js is an open source and cross-platform JavaScript runtime environment;
  • Node.js runs the V8 JavaScript engine outside the browser (the core of Google Chrome)
  • Node.js applications run in a single process without creating a new thread for each request
  • Node.js provides a set of asynchronous I/O native functionality in its standard library (to prevent JavaScript code from blocking), and libraries in Node.js are often written using a non-blocking paradigm (thus making blocking behavior the exception rather than the norm)
  • When Node.js performs an I/O operation (such as reading from the network or accessing a database or file system), Node.js resumes the operation when the response comes back, rather than blocking the thread and wasting CPU loops waiting
  • Node.js also implements its own Web services based on THE API file operation of JS core (ECMAScript) system level

What problem does Node solve

In Web servers, the bottleneck lies in the amount of concurrent users (multi-threaded synchronization). As long as more than one person needs to operate on the same resource, they must pass the lock

  • Each time a Java PHP user accesses the server, a new thread is created. Each thread takes up about 2MB of memory and 8GB of memory
  • Instead of creating a new thread, Node emits an event
  • Front and back end separation, write some tool library Webpack, CLI

Node is suitable for reading and writing returned files in Web application scenarios

Core Features of Node

  • Event-driven Node.js apis are event-based and asynchronous
  • Node.js uses single-threaded processes (the main thread). Node.js can start multiple processes
  • Not suitable for CPU intensive I/O intensive

Synchronous asynchronous block non-blocking (for different points)

  • Synchronous and asynchronous, focusing on the message notification mechanism readFile
    • Synchronization refers to whether the other party provides notification service when waiting for the result of an event. If the other party does not provide notification service, it is synchronization
    • Asynchrony refers to whether the other party provides notification service when waiting for the processing result of a matter. If the other party provides notification service, it is asynchrony.
  • The state in which blocking and non-blocking programs wait for message results
    • Block, while waiting for the result of one thing, whether you still do something else, if not, it is blocked;
    • Non-blocking, whether you do something else while waiting for the result of one thing, and if so, non-blocking;

Global object in Node

This and Module. exports are ===

  console.log(this); // {} this is not global
  console.log(this= = =global); // false
  console.log(this= = =module.exports); // true
Copy the code

arguments

  console.log(arguments);
  // [Arguments] {
  //   '0': {},
  // '1': [Function: require] {
  // resolve: [Function: resolve] { paths: [Function: paths] },
  // main: Module {
  // id: '.',
  // path: '/Users/hiraku/myself/architecture-product/node/4.global',
  // exports: {},
  // parent: null,
  // filename: '/Users/hiraku/myself/architecture-product/node/4.global/index.js',
  // loaded: false,
  // children: [],
  // paths: [Array]
  / /},
  // extensions: [Object: null prototype] {
  // '.js': [Function],
  // '.json': [Function],
  // '.node': [Function],
  // '.mjs': [Function]
  / /},
  // cache: [Object: null prototype] {
  // '/Users/hiraku/myself/architecture-product/node/4.global/index.js': [Module]
  / /}
  / /},
  // '2': Module {
  // id: '.',
  // path: '/Users/hiraku/myself/architecture-product/node/4.global',
  // exports: {},
  // parent: null,
  // filename: '/Users/hiraku/myself/architecture-product/node/4.global/index.js',
  // loaded: false,
  // children: [],
  // paths: [
  // '/Users/hiraku/myself/architecture-product/node/4.global/node_modules',
  // '/Users/hiraku/myself/architecture-product/node/node_modules',
  // '/Users/hiraku/myself/architecture-product/node_modules',
  // '/Users/hiraku/myself/node_modules',
  // '/Users/hiraku/node_modules',
  // '/Users/node_modules',
  // '/node_modules'
  / /]
  / /},
  // '3': '/Users/hiraku/myself/architecture-product/node/4.global/index.js',
  // '4': '/Users/hiraku/myself/architecture-product/node/4.global'
  // }
Copy the code

global key

  console.log(Object.keys(global));
  / / /
  // 'global',
  // 'clearInterval',
  // 'clearTimeout',
  // 'setInterval',
  // 'setTimeout',
  // 'queueMicrotask',
  // 'clearImmediate',
  // 'setImmediate'
  // ]
Copy the code

Process process

  console.log(Object.keys(process));
  // ['version','arch','platform','release','_rawDebug','moduleLoadList','binding','_linkedBinding','_events','_eventsCount', '_maxListeners','domain','_exiting','config','abort','umask','chdir','cwd','_debugProcess','_debugEnd','_startProfilerId leNotifier','_stopProfilerIdleNotifier','dlopen','uptime','_getActiveRequests','_getActiveHandles','reallyExit','_kill', 'hrtime','cpuUsage','resourceUsage','memoryUsage','kill','exit','getuid','geteuid','getgid','getegid','getgroups','initg roups','setgroups','setegid','seteuid','setgid','setuid','stdout','stderr','stdin','openStdin','allowedNodeEnvironmentFl ags','assert','features','_fatalException','setUncaughtExceptionCaptureCallback','hasUncaughtExceptionCaptureCallback',' emitWarning','nextTick','_tickCallback','env','title','argv','execArgv','pid','ppid','execPath','debugPort','argv0','_pr eload_modules','mainModule'
Copy the code
  • process.argv
  // node index.js --port 3000
  console.log(process.argv);
  // 1. Execute command file of the current node
  // 2. Which file is currently executing? Node + files can be executed with arguments that are placed in the third item of the array
  // 3. Parse the parameters passed by the user
  / / / '/ Users/hiraku /. NVM/versions/node/v11.10.0 / bin/node',
  // '/Users/hiraku/myself/architecture-product/node/global/index.js',
  // '--port',
  / / '3000']
  const argvObj = process.argv.slice(2).reduce((memo, current, index, arr) = > {
    if(current.startsWith(The '-')) {
      memo[current.slice(2)] = arr[index + 1];
    }
    return memo;
  }, {});
  console.log(argvObj);
Copy the code
  • Process. platform Platform on which processes run
  console.log(process.platform, 'platform'); // darwin
  // win32 darwin
Copy the code
  • The use of the commander
  const cmd = require('commander');
  cmd.name('node global');
  cmd.usage('index.js');
  cmd.version('1.0.0');
  cmd.option('-p,--port <v>'.'please set you prot ');
  cmd.option('-c,--config <v>'.'please set you config file ');
  cmd.command('create').action(() = > { // This method is executed at runtime
      console.log('Create project');
  });
  cmd.on('--help'.function () {
      console.log('\r\nRun command')
      console.log('\r\n node global -p 3000')});const r = cmd.parse(process.argv);
  console.log(r);
  console.log(process.env);
  console.log(process.cwd());

  // Usage: node global index.js

  // Options:
  // -V, --version output the version number
  // -p,--port 
      
        please set you prot
      
  // -c,--config 
      
        please set you config file
      
  // -h, --help display help for command

  // Commands:
  // create
  // help [command] display help for command

  // Run command

  // node global -p 3000
Copy the code
  • Process. CWD current working directory, such as webpack to find the configuration file, current working directory to find
  console.log(process.cwd()); // /Users/hiraku/myself/architecture-product/node/4.global
Copy the code
  • Set environment variables in the current command line window
// the window set command export command => cross-env
console.log(process.env) // The current process's environment variable uses it to distinguish between different environments
// cross-env env=development && node xxxx
Copy the code

Microtasks implemented in Node

  • Microtasks implemented in Node are prioritized over promise
  • NextTick and promise are two queues, so the nextTick queue is emptied first
  • After nodeV10, node’s event loop will perform the same as the browser, emptying microtasks after each macro task
  • The old version was to empty microtasks after each queue emptied
  process.nextTick(() = > {
    console.log(1);
    process.nextTick(() = > {
      console.log(2);
      process.nextTick(() = > {
        console.log(3);
      });
    });
  });
  Promise.resolve().then(() = > {
    console.log('promise')});// 1 2 3 promise
Copy the code
  • SetImmediate and setTimeout are affected by performance if executed with the default environment
  setImmediate(() = > { / / immediately
    console.log('setImmediate'); // Macro task in node
  });
  setTimeout(() = > {
    console.log('setTimeout');
  }, 0);
  // setTimeout
  // setImmediate
Copy the code
  • setImmediate nextTick
  setImmediate(() = > {
    console.log('setImmediate1');
    process.nextTick(() = > {
      Promise.resolve().then(() = > {
        console.log('promise1');
      });
    });
  });
  setImmediate(() = > {
    console.log('setImmediate2');
    Promise.resolve().then(() = > {
      console.log('promise2');
    });
    process.nextTick(() = > {
      console.log('nextTick2');
    });
  });
  process.nextTick(() = > {
    console.log('nextTick1');
  });

  // nextTick1
  // setImmediate1
  // promise1
  // setImmediate2
  // nextTick2
  // promise2
Copy the code
  • conclusion
    • By default, when the main code completes execution, it enters the event loop
    • The system first checks whether the current timer reaches the time. If the time reaches the time, the system performs the timer callback
    • The poll phase does the I/O callback, and if there’s no I/O see if there’s setImmediate, and if there is, it goes to the Check phase
    • If there is no timer to check if there is no timer, the I/O operation ends the loop
    • If there is a timer, the system returns to the timer phase to perform the callback of the timer after the timer expires
    • The microtask is cleared after each macro task is completed

  • Timer: This phase executes scheduling callbacks that have been setTimeout() and setInterval().

  • Pending callback: An I/O callback that is deferred until the next iteration of the loop.

  • Idle, prepare: used only in the system.

  • Polling: Retrieves new I/O events; Perform I/ O-related callbacks (in almost all cases, except for closed callback functions, those scheduled by timers and * setImmediate()), where Node will block at the appropriate time.

  • Detection: The setImmediate() callback function executes here.

  • Closed callback functions: Some closed callback functions, such as socket.on(‘close’,…) .

  • Classification of macro tasks and micro tasks

    • Vue.nextTick hybrid tasks, which can be micro tasks or macro tasks
    • Then, mutationObserver, process.nexttick
    • Macro tasks Script tags, UI rendering, MessageChannel, Ajax, Event events, setTimeout
    • setImmediate requestFrameAnimation
    • Browser is one macro task queue node is multiple macro task queues
    • The order of execution is the same