首页 > 技术文章 > 模块化开发,Node模块查找机制,Promise

article-record 2020-04-16 23:59 原文

node_modules 文件夹问题

1,文件夹以及文件过多过碎,当我们将项目整体拷贝给别人的时候,传输速度会很慢

2, 复杂的模块以来关系需要被记录,确保模块版本和当前版本保持一致,否则会导致当前项目运行报错

package.json 文件的作用

项目描述文件,记录当前项目信息,例如项目名称,版本,作者,项目依赖于哪些第三方模块等;

使用 npm init -y 生成

package-lock.json

  • 锁定包的版本,确保再次下载时不会因为包版本不同而产生问题
  • 加快下载速度,因为该文件已经记录了项目所依赖的第三方包的树状结构和包的下载地址,重新安装只需下载即可,不需要做额外的工作

项目依赖

  • 在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖;
  • 使用 npm install 包名命令下载的文件会默认被添加到 package.json 文件中的 dependencies 字段中
{
    "dependencies": {
        "jquery": "^3.3.1"
    }
}

开发依赖

  • 在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包,称为开发依赖

  • 使用 npm install packageName --save-dev 命令将包添加到 package.json 文件的 devDependencies 字段中

{
    "devDependencies": {
        "gulp": "^3.9.1"
    }
}

下载依赖

在开发和发布的过程中,是不会传输 node_modules 文件夹的,所以需要根据package.json中记录的包来进行下载

  • 开发环境中需要下载所有的依赖:npm install

  • 生产环境只需要下载项目依赖:npm install --production

Node.js 中模块查找机制

// require方法根据模块路径查找模块,如果是完整路径,直接引入模块
require('./find.js');
// 1. 如果省略后缀,先找同名js文件,再找同名文件夹
// 2. 如果找到同名文件夹,找文件夹中的index.js
// 3. 如果文件夹中没有index.js 就会去当前文件夹中package.json中查找main选项的入口文件是哪个执行这个文件
// 4. 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到
require('./find');
// 1. 如果省略后缀和路径,Node会把它当做一个系统模块
// 2. 先去node_modules文件夹中 首先看是否有该名字的js文件
// 3. 再看是否有该名字的文件夹,如果有看里面是否有index.js
// 4. 如果没有查看该文件夹中 package.json文件中的main选项指定的文件,如果还没有报错
require('find');

promise

在Node.js 中存在大量的异步方法,而异步执行是无法保证代码的执行顺序的,想要保证代码的执行顺序,只有在回调函数中无尽的嵌套

fs.readFile('1.txt', (err, res1) => {
    console.log(1)
    fs.readFile('2.txt', (err, res2) => {
        console.log(2)
        fs.readFile('3.txt', (err, res3) => {
            console.log(3)
        })
    })
})

Promise 出现的目的就是为了解决Node.js异步编程中回调地狱的问题

let promise = new Promise((resolve, reject) => {
  let flag = false
  setTimeout(() => {
    if (flag) {
      console.log('success')
    } else {
      console.log('error')
    }
  }, 2000);
})
// .then对应构造函数 resolve .catch对应reject
promise.then(result => console.log(result)).catch(error => console.log(error))
const read = (url) => {
  return new Promise((resolve, reject) => {
    fs.readFile(url, 'utf8', (err, result) => {
      if (err != null) {
        reject(err);
        return
      }
      resolve(result)
    })
  })
}
read('./http.js')
.then(result  => {
  console.log(result)
  return read('./modul-a.js')
}).then(result => {
  console.log(result)
  return read('./modul-b.js')
}).then(result => {
  console.log(result)
})

异步函数

异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的方式,让代码不再有回调函数的嵌套,使代码变得清晰明了

const fn = async () => {}
async function fn() {}

async 关键字

  • 普通函数定义前面加 async 关键字,普通函数变为异步函数
  • 异步函数默认返回 promise 对象
  • 在异步函数内部使用return关键字进行结果返回 结果会被包裹在promise 对象中,return 关键字代替了 resolve 方法
  • 在异步函数内部使用 throw 关键字抛出程序异常
  • 调用异步函数在链式调用 then 方法获取异步函数执行结果
  • 调用异步方法函数在链式调用 catch 方法获取异步函数中的错误信息

await关键字

  • await 关键字只出现与异步函数中
  • await promise await后面只能写promise对象
  • await 关键字可是暂停异步函数向下执行,知道promise返回结果

推荐阅读