Goland工具开发NodeJs - Go语言中文社区

Goland工具开发NodeJs


一、Node环境配置

(1)加载Node模块

第一步:打开setting -> Language & Frameworks -> JavaScript -> Libraries,界面如下所示:

第二步:点击Download,下载node模块。下载完成后界面如下图所示:

第三步:修改JavaScript版本为ECMAScript6。

配置完成后,重启一下Goland即可。

 

二、node.js基本语法

(1)定义变量和常量

方式一:var 变量名 = 值

方式二:let 变量名 = 值

第一种方式定义的变量可以被重新定义,第二种方式定义的变量不能够被重新定义。所以,基于安全性考虑,推荐使用let关键字定义变量。

定义常量:const 常量名 = 常量值

注意:1)定义常量时候需要指定具体的值;2)常量一旦定义之后,它的值不能够被改变;

(2)解构

作用:简化代码。

例如:对数组解构。

let arr = [1, 2, 3, 4, 5, 99]
let [a, b, c, d] = arr // 把arr数组中前4个元素赋值给a b c d四个变量
console.log(a, b, c, d)

例如:解构对象。

const person = {
    name : 'lily',
    age : 18
}
let {name, age} = person
console.log(name, age)

注意:如果解构对象时候目标变量的顺序或变量名与结构体不一样,那么就要明确指定对应的名字。

const person = {
    name : 'lily',
    age : 18
}
let {name:newName, age} = person
console.log(newName, age)

当对象作为函数参数的时候,也可以解构。

const person = {
    name : 'lily',
    age : 18
}

function print({name, age}) {
    console.log(`姓名:${name}, 年龄:${age}`) // 注意:这里不能使用单引号
}

print(person)

(3)函数定义

方式一:传统方式创建函数。

function add(a, b) {
    return a + b
}

方式二:使用箭头函数。

let add = (a, b) => {
    return a + b
}

如果函数体只有返回值,那么也可以写成这样:

let add = (a, b) => a + b

(4)类

ECMAScript6支持class关键字定义类,其语法与java语言类似。

class Person {

    constructor(name, age) {
        this.name = name
        this.age = age
    }

    say() {
        console.log(`my name is ${this.name}, i am ${this.age} years old.`)
    }
}

细节问题:

1)在class中可以使用construct定义构造函数。当创建对象时候会自动调用构造函数,不需要自己手动调用。

2)上面构造函数中使用this对Person对象的name和age属性进行了初始化。this代表当前的Person对象。

3)在class中也可以定义方法,但是class中的方法不需要使用function关键字。

与Java语言类似,可以使用extends关键字继承类。

class Student extends Person {

    constructor(name, age) {
        super(name, age)
    }

    say() {
        console.log(`the student's name is ${this.name}, he is ${this.age} years old.`)
    }
}

上面程序Student类继承了Person类,那么Student类就是Person类的子类。因此,Student就拥有了Person类中的所有成员属性和成员方法。

值得注意的是,在子类构造函数中需要显示地调用父类的构造函数。super(...)的作用就是调用父类的构造函数。

子类可以定义父类同名的方法。如果通过子类对象调用同名方法,那么默认会调用子类的方法,而不是父类方法。

如果要创建class对象,那么可以使用new关键字。

let stu = new Student("mi", 19);
stu.say()

(5)异步编程

node.js的异步编程是通过回调函数来实现的。下面以读取文件为例:

// 1.导入fs模块,该模块是由node.js提供
let fs = require('fs')

// 2.异步读取文件
fs.readFile('1.txt', 'utf-8', function(err, data) {
    if (err) {
        console.log("读取文件失败!")
        return
    }
    console.log(`${data}`)
})

从面代码通过异步方式读取1.txt文件的内容。其中,在readFile函数的第三个参数就是一个回调函数。该回调函数是在文件读取完毕后,系统自动调用。node.js中大量使用了回调函数来实现异步通信。回调函数一般作为函数的最后一个参数传递进来。

(6)模块导入导出

06_模块导出.js

function printA() {
    console.log("printA...")
}

function printB() {
    console.log("printB...")
}

// 执行导出
module.exports = {
    printA,
    printB,
}

06_模块导入.js

let ex = require("./06_模块导出")
ex.printA()
ex.printB()

require可以对导入系统内置模块、也可以导入第三方或自己实现的模块。

使用require导入模块,一定要有对应的导出。

如果是自己实现的模块,导入时候要明确指定路径。路径要以./开头,不需要后缀名。

(7)path模块

path模块提供了一些操作文件路径的方法,简化了文件路径的操作。

let path = require("path")

// 返回一个路径的最后一部分
console.log("basename : ", path.basename('D:\code\go_workspace\src\Project014\1.txt'))
// 返回一个路径的目录部分
console.log("dirname : ", path.dirname('D:\code\go_workspace\src\Project014\1.txt'))
// 返回一个文件的扩展名
console.log("extname : ", path.extname('D:\code\go_workspace\src\Project014\1.txt'))
// 拼接给定的路径片段
console.log("join : ", path.join('D:\code', '\go_workspace', '\src', '\Project014', '\1.txt'))
// 把一个不规范的路径修改为规范路径
console.log("normalize : ", path.normalize('D:\code\\\go_workspace\src\\Project014/1.txt'))
// 基于当前执行目录,返回一个绝对路径
console.log("resolve : ", path.resolve('1.txt'))

(8)fs模块

fs模块提供了一些操作文件的方法。常用方法如下:

fs.stat/fs.statSync:访问文件的元数据,比如文件大小,文件的修改时间。

fs.readFile/fs.readFileSync:异步/同步读取文件。

fs.writeFile/fs.writeFileSync:异步/同步写入文件。

fs.readdir/fs.readdirSync:读取文件夹内容。

fs.unlink/fs.unlinkSync:删除文件。

fs.rmdir/fs.rmdirSync:只能删除空文件夹。如果要删除非空文件夹,可以借助第三方模块fs-extra 来实现。

fs.watchFile:监视文件的变化。

let fs = require("fs")

// 读文件
fs.readFile("1.txt", "utf-8", (err, data) => {
    if (err) {
        console.log("读文件失败!")
        return
    }
    console.log("读到的内容:", data)
})

// 写文件
fs.writeFile("2.txt", "hello world", (err) => {
    if (err) {
        console.log("写文件失败!")
        return
    }
    console.log("写文件成功!")
})

// 读取文件状态
let stat = fs.statSync("1.txt")
console.log("文件大小:", stat.size)
console.log("是否是文件:", stat.isFile())
console.log("是否是目录:", stat.isDirectory())

// 删除文件
fs.unlinkSync("2.txt")

(9)定义Promise

Promise的作用是对异步回调代码包装一下,把原来的一个回调函数拆成2个回调函数,从而提高程序的可读性。

比如下面代码:

let fs = require("fs")

fs.readFile("1.txt", (err, data) => {
    if (err) {
        console.log("读文件失败!")
        return
    }
    console.log("读取到的内容:", res.toString())
})

如果使用Promise来实现,代码如下所示:

let fs = require('fs')

// 1.使用Promise对readFile函数进行包装
let readFilePromise = new Promise(function (resolve, reject) {
    fs.readFile("1.txt", (err, data) => {
        if (err) {
            reject(err)
        } else {
            resolve(data)
        }
    })
})

// 2.调用Promise对象的then和catch方法
readFilePromise.then(res => {
    console.log("读取到的内容:", res.toString())
}).catch(err => {
    console.log(err)
})

调用then方法需要传入回调函数作为参数,回调函数的参数就是resolve(data)中的data参数。

调用catch方法也要传入回调函数作为参数,回调函数的参数就是reject(err)中的err参数。

(10)async和await

如果需要对多个异步函数封装成Promise,那么需要使用async和await来实现异步调用。

比如下面代码:

let fs = require("fs")

fs.readFile("1.txt", (err, data) => {
    if (err) {
        console.log("读文件失败!")
        return
    }
    fs.writeFile("2.txt", data, (err) => {
        if (err) {
            console.log("写文件失败!")
            return
        }
        fs.stat("2.txt", (err, stat) => {
            if (err) {
                console.log("读取文件状态失败!")
                return
            }
            console.log(stat)
        })
    })
})

上面代码中有多个异步函数,如果使用Promise来实现,首先要为每一个异步函数都使用一个Promise进行包装。

let fs = require('fs')

// 1.创建一个Promise,对fs.readFile进行封装
let readFilePromise = () => {
    return new Promise(function (resolve, reject) {
        fs.readFile("1.txt", (err, data) => {
            if (err) {
                reject(err)
            } else {
                resolve(data)
            }
        })
    })
}

// 2.创建一个Promise,对fs.writeFile进行封装
let writeFilePromise = (data) => {
    return new Promise(function (resolve, reject) {
        fs.writeFile("2.txt", data, (err) => {
            if (err) {
                reject(err)
            }
        })
    })
}

// 3.创建一个Promise,对fs.stat进行封装
let readStatPromise = () => {
    return new Promise(function (resolve, reject) {
        fs.stat("2.txt", (err, stat) => {
            if (err) {
                reject(err)
            } else {
                resolve(stat)
            }
        })
    })
}

然后再定义一个函数,该函数负责调用上面的readFilePromise、writeFilePromise和readStatPromise函数。

let checkStat = async() => {
    try {
        let data = await readFilePromise()
        await readFilePromise()
        console.log("读写成功!")
        let stat = await readStatPromise()
        console.log(stat)
    } catch (e) {
        console.log(e)
    }
}
checkStat()

在async函数中的每一个函数调用,都需要使用await修饰。async函数必须要等到方法体中所有await修饰的Promise函数执行完后,async函数才会得到一个resolve状态的Promise对象。如果执行async函数过程中一旦其中一个异步函数发生异常,那么整个async函数终止执行,并抛出异常对象给catch处理。如果在catch中返回reject(),那么async函数就会得到一个reject状态的Promise对象。

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zhongliwen1981/article/details/89894448
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-06 09:34:34
  • 阅读 ( 1922 )
  • 分类:Goland

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢