Node.js

NodeJS操作文件

引入文件模块

var fs = require("fs");

读取文件

var fs = require("fs");
//此处传入一个utf8之后,读取出来的文件数据就会自动以utf8的编码方式转换成我们能看懂的字符串
//(也可以通过toString()的方式转换)
fs.readFile("./db.json","utf8",function(error,data){
    if(error){
        return response.status(500).send("Server error.");
    }
    //从文件中读取到的数据一定是字符串
    //所以一定要手动转成对象才能够去渲染模板
    var students = JSON.parse(data).students;
});

异步编程(回调函数)

js中的函数

  • 是一种数据类型
  • 能作为参数
  • 能作为返回值
  • 非常灵活,无所不能
  • 一般情况下,把函数作为参数,就是为了获取函数内部的异步操作结果
  • JavaScript 单线程、时间循环

获取函数内部异步操作的结果

无法直接获取:

function add(x,y){
    console.log(1);
    setTimeout(function(){
        console.log(2);
        var ret = x+y;
        return ret;
    },1000);
    console.log(3);
    //到这里执行就世结束了,不会等到前面的定时器,所以直接就返回了默认值 undefined
}

console.log(add(10,20)); //结果为undefined

使用回调函数获取:

凡是要得到一个函数内部异步操作的结果(setTimeout、readFile、writeFile、ajax),必须通过回调函数,并且异步API都伴有一个回调函数。

function add(x,y,callback){
    //callback 就是回调函数
    console.log(1);
    setTimeout(function(){
        var ret = x+y;
        callback(ret);
    },1000);
}

add(10,20,function(ret){
    console.log(ret);
});

基于原生XMLHTTPRequest 封装 get 方法:

function get(url,callback){
    var oReq = new XMLHttpRequest();
    //当请求加载成功之后要调用指定的函数
    oReq.onload = function(){
        //现在需要得到这里的 oReq.responseText
        callback(oReq.response);
    }
    oReq.open("get",url,true);
    oReq.send();
}
get("./data.json",function(data){
    console.log(data);
});

Express

在Express中配置使用 art-template模板引擎

安装:

npm install --svae art-template
npm install --save express-art-template

配置:

app.engine(".html",require("express-art-template"));

使用:

app.get("/admin",function(request,response){
    //默认会去views目录下找
    //渲染模板时只需要在文件后 加一个数据参数即可
    response.render("admin/index.html",{
        title : "管理系统"
    });
});

Express 获取表单 GET 请求参数

Express 内置了一个API,可以直接通过 request.query 来获取

request.query;

Express 获取表单 POST 请求参数

在Express中没有内置获取表单POST请求体的API,这里我们需要使用一个第三方包: body-parser

安装:

npm install --save body-parser

配置:

//引入express框架
var express = require("express");
//引包
var bodyParser = require("body-parser");

var app = express();

//配置 body-parser
//只要加入这个配置,则在request请求对象上会多出来一个属性:body
//也就是说可以直接通过 request.body来获取表单 post 请求体中的数据了 
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

使用:

app.post("/post",function(request,response){
    //1、获取表单请求参数
        //request.query 只能拿到 get 请求参数
        //console.log(request.query);
     let comment = request.body;

    //2、处理
    comment.dateTime = "2019年9月18日 15:29:31";
    comments.unshift(comment); 

    //3、发送响应(重定向到主页)
    response.redirect("/");
});

Promise

无法保证顺序的代码:

var fs = require("fs");

fs.readFile("./data/a.txt","utf8",function(error,data){
    if(error){
        // return console.log("读取失败");

        /*
            抛出异常
                1、阻止程序的执行
                2、把错误信息打印到控制台
         */
        throw error;
    }
    console.log(data);
});

fs.readFile("./data/b.txt","utf8",function(error,data){
    if(error){
        throw error;
    }
    console.log(data);
});

fs.readFile("./data/c.txt","utf8",function(error,data){
    if(error){
        throw error;
    }
    console.log(data);
});

通过回调嵌套的方式来保证顺序:

var fs = require("fs");

fs.readFile("./data/a.txt","utf8",function(error,data){
    if(error){
        // return console.log("读取失败");

        /*
            抛出异常
                1、阻止程序的执行
                2、把错误信息打印到控制台
         */
        throw error;
    }
    console.log(data);
    
    //a执行完毕之后调用b
    fs.readFile("./data/b.txt","utf8",function(error,data){
        if(error){
            throw error;
        }
        console.log(data);
        //b执行完毕之后调用c
        fs.readFile("./data/c.txt","utf8",function(error,data){
            if(error){
                throw error;
            }
            console.log(data);
        });
    });
});

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在EcmaScript 6 中新增了一个API:Promise

  • Promise 的英文就是承诺、保证的意思
  • Promise本身不是异步,但是内部往往封装的是异步任务

Promise基本语法:

//在EcmaScript 6 中新增了一个API Promise
//Promise 是一个构造函数

var fs = require("fs");

//创建一个 promise 容器
var p1 = new Promise(function(resolve,reject){//Promise 容器一旦创建就执行里面的代码
    fs.readFile("./data/a.txt","utf8",function(error,data){
        if(error){
            //失败了,承诺容器中的任务失败了
            //console.log(error);
            //把容器的Pending 状态变为 Rejected
            reject(error);
        }else{
            //承诺容器中的任务成功了
            //console.log(data);
            //把容器的Pending状态改为成功 Resolved
            resolve(data);
        }
    });
});

Promise链式调用:

var fs = require("fs");

//创建一个 promise 容器
var p1 = new Promise(function(resolve,reject){//Promise 容器一旦创建就执行里面的代码
    fs.readFile("./data/a.txt","utf8",function(error,data){//这是一个异步任务
        if(error){
            //失败了,承诺容器中的任务失败了
            //console.log(error);
            //把容器的Pending 状态变为 Rejected
            reject(error);// ===>失败调用
        }else{
            //承诺容器中的任务成功了
            //console.log(data);
            //把容器的Pending状态改为成功 Resolved
            resolve(data);// ===>成功调用
        }
    });
});

var p2 = new Promise(function(resolve,reject){
    fs.readFile("./data/b.txt","utf8",function(error,data){
        if(error){
            reject(error);
        }else{
            resolve(data);
        }
    });
});


var p3 = new Promise(function(resolve,reject){
    fs.readFile("./data/c.txt","utf8",function(error,data){
        if(error){
            reject(error);
        }else{
            resolve(data);
        }
    });
});

p1.then(function(data){
    console.log(data);
    /*
        当p1读取成功的时候
        当前函数中 return 的结果就可以在后面的 then 中的 function 中接受到
            当return 123 时,后面就接受到1233
            当return "hello" 时,后面就接受到 "hello"
            没有 return 后面收到的就是 undefined
        上面那些 return 的数据没什么卵用
        真正有用的是: 可以 return 一个 Promise 对象
        当 return 一个 Promise 对象的时候,后续的 then 中的 function 的第一个参数会作为p2的 resolve
    */
   return p2;
},function(error){
    console.log(error);
})
.then(function(data){//上面return的什么,这里的data接受到的就是什么,若return的是Promie对象,则此处则将function作为Promise的resolve
    console.log(data);
    return p3;
})
.then(function(data){
    console.log(data);//同理,上面return什么,这里的data就是什么,若return的是Promie对象,则此处则将function作为Promise的resolve
});

封装Promise API:

var fs = require("fs");

//封装
var pReadFile = function(filePath){
    return new Promise(function(resolve,reject){
        fs.readFile(filePath,function(error,data){
           if(error){
                reject(error);
           } else{
                resolve(data);
           }
        });
    });
}

//调用
pReadFile("./data/a.txt")
    .then(function(data){
        console.log(data)
        return pReadFile("./data/b.txt");
    })
    .then(function(data){
        console.log(data);
        return pReadFile("./data/c.txt");
    })
    .then(function(data){
        console.log(data);
    });
posted @ 2021-08-09 21:23  奇怪的阿峰  阅读(53)  评论(0)    收藏  举报