1.res.send()和 res.end()的差别
(1)res.write + res.end
http.createServer(function (req, res) { if(results[0])[ res.write("<html>") res.write("<head>") //... res.write("</html>") res.end(); }
现在都直接用res.render("index.ejs",{})输出网页
(2)res.send = res.write + res.end
后来大家都直接用 send
app.get("/", function (req, res) { res.send("OK, Home page...."); })
2.资料库Update (档案Lab > 15_资料库_UpdateDelect)
(1)
npm install
npm start (nodemon app.js)
(2)Update
当使用者点击编辑:资料放在编辑页面上SPA(没有另跳页面)
特性:使用JS编辑(rel="modal:open"),server只给值
(3)HTML
<!-- modal:open 另跳视窗开启 --> <a href="#ex1" rel="modal:open"> <button onclick="Edit(<%= item.id%>)">编辑</button></a> <button onclick="Delete(<%= item.id%>)">删除</button>
(4)index.ejs > 取值
function Edit(id) { $.ajax({ url: "/detail/"+id, type: "GET", success: function(res) { var res = JSON.parse(res) //res.data 指 success.data //将值传递进input裏头 $("input[name='id']").val(res.data.id) $("input[name='name']").val(res.data.name) $("input[name='phone']").val(res.data.phone) $("input[name='address']").val(res.data.address) $("input[name='adult_mask']").val(res.data.adult_mask) $("input[name='child_mask']").val(res.data.child_mask) }, error: function() { alert("系统错误!") }, }) }
(5)index.js > SQL语法
1.取值显示在编辑页面上,2.页面回传Success or Error
index.get('/detail/:id([0-9]+)', function(req, res){ var sql = `SELECT * FROM inventory WHERE id = ?;` var data = [req.params.id] // exec MySQL的引用 db.exec(sql, data, function(results, fields) { if(results[0]){ //第0笔资料 res.end( JSON.stringify(new Success(results[0])) ) } else { res.end( JSON.stringify(new Error('no result')) ) } }) })
(6)response.js > Success or Error输出data(此处)或message
class Success { constructor(data, message) { if(typeof data === 'string') { this.message = data data = null message = null } if(data) { this.data = data } if(message) { this.message = message } this.errno = 1 } }
(7)编辑送出
$('#submit').on('click', function() { //整理表单资料到变数 var data = $('#form').serializeArray() //form表单内资料转成阵列 JSONData = serializeToJSON(data) //用post方法丢json格式的data到 /update //阵列资料转Json物件 ajax才能使用 $.ajax({ url: "/update", //index.js > exec方法输出 type: "POST", contentType: "application/json; charset=utf-8", data: JSONData, success: function(res) { var res = JSON.parse(res) if(res.errno === 1) { alert(res.message +"更新成功!") location.reload() } else if(res.errno === 0) { alert("更新失败!") } }, error: function() { alert("系统错误!") } }) })
(8)response.js > Success or Error输出data或message(此处)
class Success { constructor(data, message) { if(typeof data === 'string') { this.message = data data = null message = null } if(data) { this.data = data } if(message) { this.message = message } this.errno = 1 } }
3.资料库Delect (档案Lab > 15_资料库_UpdateDelect)
(1)HTML
<!-- modal:open 另跳视窗开启 --> <a href="#ex1" rel="modal:open"> <button onclick="Edit(<%= item.id%>)">编辑</button></a> <button onclick="Delete(<%= item.id%>)">删除</button>
(2)index.ejs
function Delete(id) { var JSONData = {"id": id} JSONData = JSON.stringify(JSONData) $.ajax({ url: "/delete", type: "POST", contentType: "application/json; charset=utf-8", data: JSONData, success: function(res) { var res = JSON.parse(res) if(res.errno === 1) { alert("删除成功!") location.reload() } else if(res.errno === 0) { alert("删除失败!") } }, error: function() { alert("系统错误!") } }) }
(3) index.js > exec方法输出
index.post('/delete', function(req, res){ var body = req.body var sql = `DELETE FROM inventory WHERE id = ?;` var data = [parseInt(body.id)] //转数值 db.exec(sql, data, function(results, fields) { //使用affectedRows,判断是否有被删除 if(results.affectedRows){ res.end( JSON.stringify(new Success('delete success')) ) } else { res.end( JSON.stringify(new Error('delete failed')) ) } }) })
(3)response.js > Success or Error输出data或message(此处)
class Success { constructor(data, message) { if(typeof data === 'string') { this.message = data data = null message = null } if(data) { this.data = data } if(message) { this.message = message } this.errno = 1 } }
4.Bludbird (档案JavaScript > 09_promise)
(1)promise使用then的方法
(2)promise解决Callback Hell
bludbird套件使用promise解决Callback Hell(就不会曹套)
(3)promise物件
function longTimeWork(workFine = true, errorMessage = "test") { return new Promise( (resolve, reject) => { // 3.取得承诺物件 setTimeout( () => { (workFine) ? resolve(200) : reject(errorMessage); }, 1000); }) }
(4)async + await (promise才有await)
成功//200
失败//test02
async function usingLongTimeWork() { try { var result = await longTimeWork(workFine, "test02"); console.log(result); } catch (e) { console.log(e); //"test" } }
5.Promise await + async(必要)(档案JavaScript > 09_promise)
await用处:等待时间,计算仓库剩几张票,再继续卖剩下的票
避免同时多人同时购票,且电脑有时间计算票数
(1)取得承诺物件
function longTimeWork(workFine = true, errorMessage = "test") { return new Promise( (resolve, reject) => { // setTimeout( () => { (workFine) ? resolve(200) : reject(errorMessage); // 5.收到,跑程式 }, 1000); //1000 = 1秒 }) }
(1-2)非同步 async + await
async function main2() { var p = await longTimeWork(true, "test"); // 2.呼叫function ; await console.log(p); //200 } main2()
(1-3)想要有 成功 与 失败 的输出分类时
function usingLongTimeWork() { longTimeWork(true, "test") // try true/false .then(function (e) { // 成功时:resolve(200) ; e变数 console.log('ok2yoyo'+ e); //ok2yoyo200 }) .catch(function (e) { // 失败时:reject(errorMessage) console.log('ok3'+ e); }) }
(2)02_AsyncAwait:(1)的综合简写 + =>函式
Promise + await (无须then 已内建)
function longTimeWork(workFine = true, errorMessage = "test") { return new Promise( (resolve, reject) => { //取得承诺物件 setTimeout( () => { (workFine) ? resolve(200) : reject(errorMessage); }, 1000); }) } //想要有 成功 与 失败 的输出分类时 async function usingLongTimeWork() { try { //longTimeWork( true / false , "test") var result = await longTimeWork(false, "test"); console.log(result); } catch (e) { console.log(e); //"test" } console.log("123") } usingLongTimeWork();
(3)03_testOnHtml (Promise + await)
function longTimeWork(workFine = true, errorMessage = "test") { return new Promise((resolve, reject) => { setTimeout(() => { workFine ? resolve(200) : reject(errorMessage); }, 5000); }); } async function usingLongTimeWork(isOK) { try { var result = await longTimeWork(isOK, "test"); console.log(result); } catch (e) { console.log(e); } } console.log("flag A"); usingLongTimeWork(true); //200(五秒后出现) console.log("flag B"); usingLongTimeWork(false); //test(五秒后出现) console.log("flag C");
(4)非同步 async + await(总共用5秒)
async function living() { var total = 0; var result1 = await happy(200, 2000); // result1 跑完才往下执行 console.log(result1); var result2 = await sad(-100, 3000); // 等result1跑完 result2 才执行 console.log(result2); total = result1 + result2; console.log("total:", total); }
(5)同步进行 async + 变数 + await(总共用3秒)
async function living() { var promise1 = happy(200, 2000); var promise2 = sad(-100, 3000); var result1 = await promise1; var result2 = await promise2; //同时进行,但等待完才将答案送到结果,所以只花3秒钟 var total = result1 + result2; console.log("total:", total); }
(6)5进化版[,]
async function living() { var promise1 = happy(200, 2000); var promise2 = sad(-100, 3000); let [result1, result2] = await Promise.all([promise1, promise2]); //需要同步进行时,塞在同一的阵列 var total = result1 + result2; console.log("total:", total); }
(7)更偷懒 直接塞方法(省略仓库)
async function living() { let [result1, result2] = await Promise.all([happy(200, 2000), sad(-100, 3000)]); //省略仓库 var total = result1 + result2; console.log("total:", total); }
6.await使用 Demo > ticket资料夹
举例:1个商品有3个人同时购买
但刚好在同一秒钟,三个人同时点下购入,会变成3个人都交易成功
为了避免,就要使用这个方法
(1)Demo_Multi_Users(SQL_Server)
顾客买商品各一个:Demo_Multi_Users(SQL_Server) > ClientA、B、C.sql
此时会导致资料库误读,因为同时购买
select @count = UnitsInStock from Products where ProductID = 1 waitfor delay '00:00:15' //同时间00:00:15购买 update Products set UnitsInStock = @count - 1 where ProductID = 1
老师用sql server,但MySQL应该也可以使用
(2)新增资料库 MySQL
create database ticketdb default character set utf8; use ticketdb; create table concert ( concertId int auto_increment not null primary key, concertName varchar(30), count int ); insert into concert (concertName, count) values ('Jody''s last conert', 1000), ('Jeter say good-bye', 2000); select * from concert;
(3) > npm start
"scripts": { "start": "nodemon ./bin/www" },
(4) ticket.js (await + FOR UPDATE)
await req.mysql.queryAsync("start transaction", []); //交易机制SQL备份,之后rollback恢复(大家同时抢票,同时交易会同时产生订单(错误),系统出错rollback恢复,再抢一次) var data = await req.mysql.queryAsync("select * from concert where concertId = 1 for update", []); // FOR UPDATE 锁资料锁到交易完成 // 多人锁定控制 更改 (票只剩一张,只能看不能下单) // 为了确定买票只有一个人正在进行
7. CORS - SOP同源政策
去别人的伺服器抓资料
(1)通讯协定、机器名称、port号三者都必须相同才符合同源政策
(2)
var cors = require("cors"); //引用cors物件 const corsOptions = { origin: [ //把别人的伺服器放进来,跟人家要资料(别人可以拒绝 'http://www.beauty.com', 'http://localhost', ], methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS' };
methods:
Create → POST
Read → GET
Update → PUT
Delete → DELETE
8.callback - function仓库
function lab3(x, callback) { x += 1; callback(x); } lab3(20, function (value) { //value = 10 alert(value); console.log(value); }); lab3(30, (value) => { alert(value); }); lab3(40, (value) => alert(value));
9.变数 vs 参数()
变数
var a =1;
参数
function lab(x) { x += 1; alert(x); } lab(10);