node26-30

//27、review

//1
/*
<!DOCTYPE html>
<html>
	<head>
	</head>
	<body>
		<div id="button">按钮</div>
		<script type="text/javascript">
		 	button.addEventListener('click',()=>{
		 		console.log('listener1');
		 		Promise.resolve().then(()=>console.log('micro task1'));
		 	})

		 	button.addEventListener('click',()=>{
		 		console.log('listener2');
		 		Promise.resolve().then(()=>console.log('micro task2'));
		 	})

		 	button.click();

		 	//不点击时执行
		 	//listener1
			//listener2
			// micro task1
			// micro task2
			//点击按钮执行(点击button执行,点击之前,这些事件都放在宏任务队列中)
			//listener1
			//micro task1
			//listener2
			//micro task2
		</script>
	</body>
</html>
 */
/*
<!DOCTYPE html>
<html>
	<head>
	</head>
	<body>
		
		<script type="text/javascript">
		 	Promise.resolve().then(()=>{
		 		console.log('Promise1');
		 		setTimeout(()=>{
		 			console.log('setTimeout2');
		 		},0);
		 	})
		 	setTimeout(()=>{
		 		console.log('setTimeout1');
		 		Promise.resolve().then(()=>{
		 			console.log('Promise2');
		 		})
		 	},0);

		 	//Promise1
			//setTimeout1
			//Promise2
			//setTimeout2
			//宏任务[setTimeout1]   =>  [setTimeout1,setTimeout2]  =>  [setTimeout2]
		 	//微任务[Promise1]			[]								[Promise2]
		</script>
	</body>
</html>
 */
/*
//async返回的是一个promise generator+co
//await =>yield 如果产出的是一个promise,会调用这个promise.then方法
//浏览器是识别async+await  await后面跟的是promise的话默认就会直接调用这个promise的then方法
<!DOCTYPE html>
<html>
	<head>
	</head>
	<body>
		
		<script type="text/javascript">
		 	async function async1(){
		 		console.log('async1 start');
		 		await async2();
		 		console.log('async1 end');
		 		
		 		【等价替换await async2();console.log('async1 end');
		 		(1)浏览器中
		 		async2().then(()=>{
					console.log('async1 end');
		 		});
		 		(2)node中(两次then)
		 		new Promise((resolve,reject)=>resolve(async2())).then(()=>{console.log('async1 end');})
				//在node中的执行结果script start,async1 start,async2,promise1,script end,promise2,async1 end,setTimeout
		 		】
		 		 
		 	}
		 	async function async2(){
		 		console.log('async2');
		 	}
		 	console.log('script start');
		 	setTimeout(function(){
		 		console.log('setTimeout');
		 	},0);
		 	async1();
		 	new Promise(function(resolve){ //一次then
		 		console.log('promise1');
		 		resolve();
		 	}).then(function(){
		 		console.log('promise2');
		 	});
		 	console.log('script end');
		 	//默认执行 script start,async1 start,async2,promise1,script end
			//宏任务[setTimeout]   
		 	//微任务[async1 end,promise2]
		 	//结果script start,async1 start,async2,promise1,script end,async1 end,promise2,setTimeout
		 	//在node中的执行结果script start,async1 start,async2,promise1,script end,async1 end,promise2,setTimeout
		</script>
	</body>
</html>
 */

//28、node中的基本概念

//Web主要场景就是接收客户端的请求读取静态资源和渲染页面,所以Node非常适合Web应用的开发。
//阻塞和非阻塞  针对的是调用方
//>我调用了一个方法之后的状态 fs.readFile

//同步异步  针对的是被调用方
//>我调用了一个方法,这个方法会给我说他是同步的还是异步的

//异步非阻塞(我调用了一个方法,这个方法是异步的,我不想要等待这个方法执行完毕)

//http第一个请求 要计算100万个数相加,第二个请求来了,需要等待第一个人计算完成


//29、commander的用法

//node和前端的区别:前端里面有DOM、BOM,服务器端中没有window
//服务器中有global属性  全局对象

console.log(Object.keys(global));
//process 进程(很重要)
//Buffer类型 来处理二进制文件
//clearInterval clearTimeout
//setInterval setTimeout
//clearImmediate setImmediate 宏任务

//浏览器以前的方法,还是可以使用的只是默认没有被枚举出来
//console.dir(global,{showHidden:true});

//1、process默认取值时会在global中查找(node中有一个模块化系统,是以文件为单位的,每个文件都是一个模块,模块中的this被更改了 this:{})
//console.log(Object.keys(process));
//console.log(process);
//console.log(process.platform); //可以用这个属性来判断当前执行的系统环境 win32 darwin
// console.log(process.argv);//1、node.exe 2、node当前执行的文件(解析用户自己传递的参数)
//C:\Users\dptech\Desktop\test>node test.js a b c
/*
[
  'C:\\Program Files\\nodejs\\node.exe',
  'C:\\Users\\dptech\\Desktop\\test\\test.js',
  'a',
  'b',
  'c'
]
*/
//执行node文件 node文件名 a b c d (webpack --mode --config --port --progress)
//console.log(process.cwd());//当前用户的工作目录 current working directory
//console.log(process.env);//环境变量
//console.log(process.nextTick);
//result: >node test.js
//[Function: nextTick]
//console.log(process.argv);

let args = process.argv.slice(2); 
//['--port','3000','--color','red','--config','a.js'];
let obj = {};
args.forEach((item,index)=>{
    if(item.startsWith('--')){
        obj[item.slice(2)] = args[index+1];
    }
});
console.log(obj);
/*
>node test.js --port 3000 --color red --config a.js
{ port: '3000', color: 'red', config: 'a.js' }
 */

/*
commander TJ
yargs webpack           npm github
在npm上的模块都需要先安装再使用.(模块内部也提供了几个属性,也可以在模块中直接访问--参数)
 */
/*
npm init -y
npm install commander
 */
const program = require('commander');
let r = program.parse(process.argv);
/*
C:\Users\dptech\Desktop\test>node test.js  a.txt
<ref *1> Command {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  commands: [],
  options: [],
  parent: null,
  _allowUnknownOption: false,
  _args: [],
  rawArgs: [
    'C:\\Program Files\\nodejs\\node.exe',
    'C:\\Users\\dptech\\Desktop\\test\\test.js',
    'a.txt'
  ],
 */

const program = require('commander'); //--开头的是key,不带--是值
program.option('-p,--port <v>','set your port');
program.option('-c,--config <v>','set your config file');

let r = program.parse(process.argv);
console.log(r);
/*
C:\Users\dptech\Desktop\test>node test.js  -p 111 -c 222
<ref *1> Command {
  _events: [Object: null prototype] {
    'option:port': [Function (anonymous)],
    'option:config': [Function (anonymous)]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  commands: [],
  options: [
    Option {
      flags: '-p,--port <v>',
      required: true,
      optional: false,
      mandatory: false,
      negate: false,
      short: '-p',
      long: '--port',
      description: 'set your port',
      defaultValue: undefined
    },
    Option {
      flags: '-c,--config <v>',
      required: true,
      optional: false,
      mandatory: false,
      negate: false,
      short: '-c',
      long: '--config',
      description: 'set your config file',
      defaultValue: undefined
    }
  ],
  parent: null,
  _allowUnknownOption: false,
  _args: [],
  rawArgs: [
    'C:\\Program Files\\nodejs\\node.exe',
    'C:\\Users\\dptech\\Desktop\\test\\test.js',
    '-p',
    '111',
    '-c',
    '222'
  ],
  _scriptPath: 'C:\\Users\\dptech\\Desktop\\test\\test.js',
  _name: 'test',
  _optionValues: {},
  _storeOptionsAsProperties: true,
  _passCommandToAction: true,
  _actionResults: [],
  _actionHandler: null,
  _executableHandler: false,
  _executableFile: null,
  _defaultCommandName: null,
  _exitCallback: null,
  _aliases: [],
  _hidden: false,
  _helpFlags: '-h, --help',
  _helpDescription: 'display help for command',
  _helpShortFlag: '-h',
  _helpLongFlag: '--help',
  _hasImplicitHelpCommand: 0,
  _helpCommandName: 'help',
  _helpCommandnameAndArgs: 'help [command]',
  _helpCommandDescription: 'display help for command',
  program: [Circular *1],
  Command: [Function: Command],
  Option: [Function: Option],
  CommanderError: [Function: CommanderError],
  port: '111',
  config: '222',
  args: [],
  [Symbol(kCapture)]: false
}

 */

const program = require('commander');
program.version('1.0.0').command('create').action(()=>{
    console.log('创建项目');
})
.name('node')
.usage('my-server')
.option('-p,--port <v>','set your port')
.option('-c,--config <v>','set your config file')
.parse(process.argv);

console.log(process.argv);
//30、node中的eventloop

const program = require('commander');
console.log(process.cwd());//当前用户的工作目录 current working directory(这个目录可以更改,用户自己切换即可)
//当前用户在哪执行node命令时,就去哪找配置文件 webpack

console.log(__dirname);//当前文件所在的目录,这个目录是不能手动修改的

console.log(process.env);//环境变量 可以根据环境变量实现不同的功能
//window set key=value      mac export key=value 这样设置的环境变量是临时的变量
/*
C:\Users\dptech\Desktop\test>node test.js
C:\Users\dptech\Desktop\test
C:\Users\dptech\Desktop\test
{
  ALLUSERSPROFILE: 'C:\\ProgramData',
  APPDATA: 'C:\\Users\\dptech\\AppData\\Roaming',
  CLIENTNAME: 'LCCPC',
  CommonProgramFiles: 'C:\\Program Files\\Common Files',
  'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files',
  CommonProgramW6432: 'C:\\Program Files\\Common Files',
  COMPUTERNAME: 'DESKTOP-HDPMBFM',
  ComSpec: 'C:\\WINDOWS\\system32\\cmd.exe',
  DriverData: 'C:\\Windows\\System32\\Drivers\\DriverData',
  HOMEDRIVE: 'C:',
  HOMEPATH: '\\Users\\dptech',
  LOCALAPPDATA: 'C:\\Users\\dptech\\AppData\\Local',
  LOGONSERVER: '\\\\DESKTOP-HDPMBFM',
  NUMBER_OF_PROCESSORS: '2',
  OneDrive: 'C:\\Users\\dptech\\OneDrive',
  OS: 'Windows_NT',
  Path: 'C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files\\nodejs\\;D:\\Program Files\\Git\\Git\\cmd;;D:\\Program Files (x86)\\vscode\\Microsoft VS Code\\bin;C:\\Users\\dptech\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\dptech\\AppData\\Roaming\\npm',
  PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
  PROCESSOR_ARCHITECTURE: 'AMD64',
  PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel',
  PROCESSOR_LEVEL: '6',
  PROCESSOR_REVISION: '3c03',
  ProgramData: 'C:\\ProgramData',
  ProgramFiles: 'C:\\Program Files',
  'ProgramFiles(x86)': 'C:\\Program Files (x86)',
  ProgramW6432: 'C:\\Program Files',
  PROMPT: '$P$G',
  PSModulePath: 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules',
  PUBLIC: 'C:\\Users\\Public',
  SESSIONNAME: 'RDP-Tcp#1',
  SystemDrive: 'C:',
  SystemRoot: 'C:\\WINDOWS',
  TEMP: 'C:\\Users\\dptech\\AppData\\Local\\Temp',
  TMP: 'C:\\Users\\dptech\\AppData\\Local\\Temp',
  USERDOMAIN: 'DESKTOP-HDPMBFM',
  USERDOMAIN_ROAMINGPROFILE: 'DESKTOP-HDPMBFM',
  USERNAME: 'dptech',
  USERPROFILE: 'C:\\Users\\dptech',
  windir: 'C:\\WINDOWS'
}
 */

let domain = process.env.NODE_ENV == 'production'?'localhost':'zfpx.com';
console.log(process.nextTick);
//(1)微任务(node中自己实现的微任务)nextTick queueMicrotask
//node中还增加了一个
queueMicrotask(()=>{
    console.log(1);
})
setTimeout(()=>{
    console.log(2);
},0);
//执行结果1 2
//(2)node中setImmediate宏任务

//常见面试题:node中的事件环和浏览器中的区别
//微任务有哪些,宏任务有哪些

//事件环
//timer
//pending callbacks
//idle,prepare
//poll
//check
//close callbacks

//浏览器的事件环和node事件环 执行效果现在是一致的了
//进入事件环时,setTimeout有可能没有完成
setTimeout(()=>{
    console.log('timeout');
},0);
setImmediate(()=>{
    console.log('setImmeditate');
});
//结果有时是timeout->setImmediate 有时是setImmediate->timeout

//poll完成后,setImmediate->setTimeout
let fs = require('fs');
fs.readFile('./name.txt',()=>{
    setTimeout(()=>{
        console.log('timeout');
    },0);
    setImmediate(()=>{
        console.log('setImmediate');
    });
})

//process.nextTick并不属于事件环的一部分,在本轮代码执行后执行
setTimeout(()=>{
    console.log(1);
    Promise.resolve().then(()=>{
        console.log('then');
    })
    process.nextTick(()=>{
        console.log('nextTick');
    })
},0);
setTimeout(()=>{
    console.log(2);
},0);
/*
>node test.js
1
nextTick
then
2
 */
/*
(网上找的答案)
浏览器中的Event loop
浏览器的任务队列分为宏任务和微任务
宏任务:setTimeout, setInterval, setImmediate, I/O,原生事件回调函数,MessageChannel、postMessage等。
微任务:process.nextTick, 原生Promise(有些实现的promise将then方法放到了宏任务中),Object.observe(已废弃), MutationObserver等。
那么浏览器中的任务执行顺序是怎么样的呢?

1、浏览器中,先执行当前栈,执行完主执行线程中的任务。
2、取出Microtask微任务队列中任务执行直到清空。
3、取出Macrotask宏任务中 一个 任务执行。
4、检查Microtask微任务中有没有任务,如果有任务执行直到清空。
5、重复3和4。
整个的这种运行机制又称为Event Loop(事件循环)

node中的Event loop
1、在libuv内部有这样一个事件环机制。在node启动时会初始化事件环。
2、node中的event loop分为6个阶段,不同于浏览器的是,这里每一个阶段都对应一个事件队列,node会在当前阶段中的全部任务执行完,清空NextTick Queue,清空Microtask Queue,再执行下一阶段。
3、在node.js里,process 对象代表node.js应用程序,可以获取应用程序的用户,运行环境等各种信息。process.nextTick()方法将 callback 添加到next tick 队列,并且nextTick优先级比promise等microtask高。

timers:执行setTimeout() 和 setInterval()中到期的callback。
I/O callbacks:上一轮循环中有少数的I/Ocallback会被延迟到这一轮的
这一阶段执行 idle, prepare:队列的移动,仅内部使用
poll:最为重要的阶段,执行I/O callback,在适当的条件下会阻塞在这个阶段
check:执行setImmediate的callback
close callbacks:执行close事件的callback,例如socket.on("close",func)
 */



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值