node - 大杂烩

1、

在启动node项目服务时,可以为 node 传递一些参数,该参数可以在 process.argv 中获取,该属性是一个数组,第一项是:node.exe 的路径,第二项是本项目所在的路径;第三项往后是我们给 node 传递的参数:

const Koa = require('koa')
const app = new Koa()
console.log(process.argv)
app.listen()

利用process.argv我们可以做好多事情,比如:启动node服务时,端口可以在启动时自定义:

默认端口我们设置为:3000,启动服务自定义端口: node app.js 4000 或 node app.js 5000 等等。

// app.js
const Koa = require('koa')
const app = new Koa()
const port = process.argv[2] || 3000
app.listen(port, () => {
    console.log('********************服务已开启********************')
})

2、

module.exports 和exports

源码中 会把:module.exports = exports,2个指向同一个内存地址,但是当一个js文件里同时有module.exports和exports导出时,module.exports的优先级大于exports,本质上是module.exports 在导出。

也可以这么理解module.exports是大哥,exports是小弟,当大哥module.exports = {} 等于一个对象时,相当于在另开辟了一个内存空间,此时的module.exports和exports指向的已经不是一个内存地址了, exports不管怎么导出或赋值都没有用了,大哥单独玩去了,不带小弟玩了。

3、

require(x)函数的查找规则

 (1)如果是核心模块(http、path、fs等等),直接返回核心模块,并且停止查找。

(2)以 ./ 或 ../ 或 / 开头,在本地查找

       1> 如果有后缀名,按照后缀名查找对应的文件

       2> 如果没有后缀名,会按如下顺序查找:直接查找改文件x ->  查找  x.js 文件 -> 查找 x.json 文件 ->  查找 x.node 文件 ,如果没找到会报错:not fount

(3)直接是一个x,且x并不是一个核心模块,那么一般情况是一个第三方模块

如:require('test') 查找test模块,node会按照paths数组中的路径依次查找,如果未找到报错not found

4、

(1)模块在被第一次引入的时候,模块中的代码会被运行一次。

(2)模块被多次引入时,会被缓存,做种只执行(运行)一次,为什么只执行一次呢:每个模块对象module有一个loaded属性,记录当前木块是否被加载过,被加载过loaded为true。

 

5、

node采用的是深度优先算法: main -> aaa ->ccc -> ddd -> eee ->bbb

6、

在node中使用ES module 

(1)方法一

限制条件有2个:

(1)node必须高版本:

(2)文件后缀必须为  .mjs 后缀

如:

// test1.mjs
let name = 'lxc'
export {
    name
}
// test-a.mjs
import {name} from './test1.mjs'
console.log('name:', name) //输出:name: lxc

(2)方法二:

 

7、

npm  install原理

从npm5开始,npm支持缓存策略,下边图揭示了npm install时的下载流程图:

npm install会根据package.json来下载项目中包依赖,开始先检查是否有package-lock.json文件,如果没有,分析包的依赖关系,有可能这个包换依赖别的包,多个包可能会产生相同依赖情况,从远程registry仓库下载包及包的依赖,此时下载下来的是压缩包,并且会把依赖包添加至电脑缓存中去,npm会自动把依赖包解压到node_modules下,此时会生成一个pack-lock.json文件,完成安装;如果有lock文件,首先会检查pack-lock.json中的包版本和package.json中的是否一致,不一致从新构建依赖关系,走上边流程,一致的话它会优先从本地缓存中查找,如果从缓存中找到依赖包,会获取缓存中的压缩文件,把压缩文件解压到node_modules下,完成安装。

8、

接着上边7来说,如果查看npm在电脑上的缓存路径命令如下:

npm config get cache

 下边是我电脑上依赖包的缓存路径:

 

9、

清除电脑上的npm包缓存:

npm cache clean

 

10、

yarn 新npm包管理工具,早期npm不太好用(安装速度慢、版本依赖乱)

安装yarn:

npm i yarn -g

yarn 跟 npm对比图:

11、

进程、线程

进程:我们可以认为,启动一个应用程序,就会默认启动一个进程(也可能是多个进程);

线程:每一个进程中,都会启动一个线程用来执行程序中的代码,这个线程称之为主线程;

所以,我们也可以说进程是线程的容器。

一个形象的例子:操作系统类似于一个工厂,工厂中有很多车间,车间就是进程,而一个车间可能有一个以上的工人在工作,这个工人就是线程。

javascript 执行过程

上边代码执行过程:

定义变量name -》

执行log函数,函数会被压入调用栈中 -》

调用完,log函数出栈 -》

调用bar函数,被压入到调用栈中 -》

执行未结束,因为里边调用sum函数,sum被压入栈中 -》

sum执行完,出栈,-》

bar获取到结果,出栈,res结果获取到,最后log函数压入到调用栈中,执行完,出栈;

 

宏任务和微任务:

事件循环中并非只维护着一个队列,事实上是由2个队列:

DOM监听、ajax、定时器、setInterval、UIRendering都会有一个回调函数,这个回调函数就是一个任务,这个任务叫macrotask:宏任务,宏任务会被加入到红队列里边;

Promise().then() 的回调then 、Mutation Observer API、产生的是一个微任务,微任务会加入到微任务队列。

浏览器会先去执行微任务队列,全部执行完之后,然后再去执行宏任务队列,当执行完一个宏任务,执行下一个宏任务之前,都会查看微任务队列是否有任务需要执行(也就是宏任务执行之前必须保证微任务队列是空的),有的话先去执行微任务,全部执行完,然后再去执行宏任务,如此反复,直到全部执行完。

来2道面试题:

(1)

执行顺序(下边分析只是做个记录,仅供个人参考):

setTimeout 宏任务,直接放到宏任务队列,往下到2 Promise,会直接打印:'4',碰到resolve,会把2下边的then回调放到微任务队列中,接着看到3下边setTimeout,直接放到宏任务队列,往下看到4下边有打印,log会压入到调用栈中执行,输出'7', log函数出栈,往下,5下边queueMicrotask,放到微任务队列,往下,6下边又是Promise,把then回调放到微任务队列,此时会开始把微任务队列中的回调挨个压入到调用栈中执行,清空微任务队列后,会执行宏任务队列,执行1下边的setTimeout时,要注意:先打印1,下边碰到Promise,又会把then回调放到微任务队列,此时1下边的setTimeout已经执行完了,紧接着它会执行微任务队列中的回调,结果还是一个Promise,继续把Promise后边then回调放到微任务里边,继续执行,打印后边的 3,然后打印 2,最后才执行3下边的setTimeout ,输出:6

// 1
setTimeout(() => {
    console.log('1')
    new Promise((resolve) => {
        resolve();
    }).then(() => {
        new Promise((resolve) => {
            resolve()
        }).then(() => {console.log('2')})
        console.log('3')
    })
})
// 2
new Promise(resolve => {
    console.log('4')
    resolve()
}).then(() => {console.log('5')})
// 3
setTimeout(() => {console.log('6')})
// 4
console.log('7')
// 5
queueMicrotask(() => {console.log('8')})
// 6
new Promise(resolve => {
    resolve()
}).then(() => {console.log('9')})

// 正确输出结果为:4 -> 7 -> 5 -> 8 -> 9 -> 1 -> 3 -> 2 -> 6

(2)

下边这个不分析了,async中的await会阻塞线程,await后边的代码,相当于.then回调,所以a函数中的await执行完之后,后边的console.log('2')会被放到微任务队列中去!!!

async function a() {
    console.log('1')
    await b();
    console.log('2')
}
async function b() {
    console.log('3')
}
console.log('4')
setTimeout(() => {
    console.log('5')
}, 0)
a()
new Promise((resolve) => {
    console.log('6')
    resolve()
}).then(() => {
    console.log('7')
})
console.log('8')

//正确输出结果:4 -> 1 -> 3 -> 6 -> 8 -> 2 -> 7 -> 5

 

12、

发布订阅者模式:

class EventEmitter {
    constructor() {
        this._events = {}
    }
    on(eventName, callback) {
        if(!this._events[eventName]) {
            this._events[eventName] = [callback]
        }else {
            this._events[eventName].push(callback)
        }
    }
    emit(eventName) {
        if(this._events[eventName] && this._events[eventName].length) {
            this._events[eventName].forEach(cb => cb())
        }else {
            console.log('not find events!')
        }
    }
    once(eventName, callback) {
        let fn = () => {
            callback()
            this.removeEvent(eventName, fn)
        }
        this.on(eventName, fn)
    }
    removeEvent(eventName, callback) {
        if(this._events[eventName]) {
            this._events[eventName] = this._events[eventName].filter(cb => cb !== callback)
        }
    }
}
const event = new EventEmitter()
function ev() {
    console.log('触发了2')
}
// event.on('data', ev) // 绑定事件
// event.emit('data') // 触发事件
event.once('data', ev) // 只会绑定一次事件,当事件被触发之后,该事件会被删除
event.emit('data') // 触发事件

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【用于解决 failed Error: not found: python2 node-sass】 报错信息如下: ``` npm WARN prefer global node-gyp@3.6.0 should be installed with -g > node-sass@4.5.2 install E:\workspace_vscode\ww\node_modules\node-sass > node scripts/install.js Downloading binary from https://github.com/sass/node-sass/releases/download/v4.5 .2/win32-x64-48_binding.node Cannot download "https://github.com/sass/node-sass/releases/download/v4.5.2/win3 2-x64-48_binding.node": connect ETIMEDOUT 54.231.72.83:443 Timed out whilst downloading the prebuilt binary Hint: If github.com is not accessible in your location try setting a proxy via HTTP_PROXY, e.g. export HTTP_PROXY=http://example.com:1234 or configure npm proxy via npm config set proxy http://example.com:8080 > node-sass@4.5.2 postinstall E:\workspace_vscode\ww\node_modules\node-sass > node scripts/build.js gyp verb check python checking for Python executable "python2" in the PATH gyp verb `which` failed Error: not found: python2 gyp verb `which` failed at getNotFoundError ``` 这个问题有两个解决方案 1. 按照提示需要 python2 环境,安装python2环境确实可以解决, 网上好多这种(管理员身份执行)。但是当你本来就有python环境时,环境变量不能自动替换,整起来就很麻烦。 ``` npm install --global --production windows-build-tools ``` 2. 第二种解决方案 ,看另一句报错,资源被墙。 ``` Downloading binary from https://github.com/sass/node-sass/releases/download/v4.5.2/win32-x64-48_binding.node Cannot download "https://github.com/sass/node-sass/releases/download/v4.5.2/win32-x64-48_binding.node": ``` 下载此资源即可。下载后需要设置变量路径,防止它再次去下载。 可以设置环境变量 直接右键我的电脑--》属性--》高级系统设置--》环境变量--》添加 或者执行 ``` set SASS_BINARY_PATH=D:\nodejs\tools\node-sass\win32-x64-46_binding.node ``` 再次执行 npm install 成功

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值