天天看點

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

nodej 資料庫通路結果為undefined

  前幾天自己學express雖然自動路由确實很好用, 隻需要get 還有設定靜态檔案就自動路由.

  但是nodejs的異步特性有時候讓我在做資料庫連接配接時候摸不着頭腦

                                   

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

  是以到底是異步引起的還是其他的什麼引起的, 我也不是很清楚但是問題解決了是以貼出來讓大家看看.

  如果有大佬願意指教那當然是極好的

具體讓我們看看問題

使用環境

  安裝環境

|- node.js
|- express ejs(模闆渲染) 
|- mysql(資料庫) 
|- npm 包管理器
           

  npm 包

|- mysql(連接配接mysql 資料庫) 
|- ejs(用于模闆渲染)  
|- express(架構) 
|- url(用于路由) 
|- body-parser(接收post 請求)
           

整體方式

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

三種響應:

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs
nodejs 實戰項目學習 資料庫通路結果為undefined express ejs
nodejs 實戰項目學習 資料庫通路結果為undefined express ejs
目錄結構
|-father
	|-node-modules
		...npm包
    |-public
        |-css
            ...
        |-image
            ...
        |-js
        	...
    |-views
        index.html
        game-frist.html
        game-second.html
    Test.js
	package.json
           
實際操作中遇到的問題

  因為資料庫是異步的是以在響應結果的時候必須加上異步, 不然結果集就會是undefined, 而且前面還必須加上事先對資料庫的通路

Test.js

const express = require('express'); // 導入express子產品
const ejs = require('ejs'); // 加入ejs子產品
const app = express(); // 建立express
const url = require('url');

// app.set('view engine', 'ejs'); 把ejs注入到express, 并設定視圖字尾名為ejs
app.set('view engine', 'html'); // 這個是設定字尾名為html
app.engine('.html', require('ejs').__express);

let dealData = require('getdata');
dealData.getData(0); // 不能省略
// 初始化變量不能省

let userData = require('userData');
// 直接調用沒有效果 要在get post調用才有用

// 可能這個時候資料庫還沒有初始化
// console.log(userData.getUser(123), 'Test');

// 對使用者資料庫操作的子產品

// 3.引入body-parser子產品 獲得前端後手送出的資料
let bodyParser = require('body-parser');
// 4.建立 application/x-www-form-urlencoded 編碼解析 接收post的資料流所用
let urlencodedParser = bodyParser.urlencoded({
	extended: false
});


// 設定視圖檔案的目錄為: dirname + '/views';
// 可設定任意位置為視圖檔案根目錄 預設是路徑為目前檔案所在的目錄下的views目錄
// 就像下面
app.set('views', __dirname + '/views');

app.use(express.static(__dirname + "/public"));

app.get('/', function(req, res) {
	// console.log(dealData.getData(0))
	let loginFlag = {
		idFlag: false,
		pwd: false
	};
	let resultSet = dealData.getData(0);
	resultSet.loginFlag = loginFlag;
	res.render('index', resultSet);
});
//  這個東西是按順序比對的
app.post('/login', urlencodedParser, function(req, res) {
	var userId = req.body.userId;
	var pwd = req.body.pwd;
	let loginFlag = {
		idFlag: false,
		pwd: false
	};

	userData.getUser(userId);
	// 這個地方有異步
	// 如果不事先載入檔案就會出錯
	setTimeout(function() {
		var personData = userData.getUser(userId);
		// 如果不進行異步處理實作加載資料庫就會傳回undefined 
		// 就是沒有執行到傳回語句就會直接按預設沒有傳回執行
		// 判斷是否有結果, 如果沒有pwd 或 使用者名其中之一直接重繪
		if(personData.userMessage != undefined) {
			// 如果數組長度不為零 判斷數組是否為空
			if (personData.userMessage.length != 0) {
				// 使用者名正确
				if (personData.userMessage[0].id == userId) {
					loginFlag.idFlag = true;
					// 密碼正确
					if (personData.userMessage[0].pwd == pwd) {
						loginFlag.pwd = true;
					} else {
			
					}
				}
				// 使用資料庫做處理
				// 驗證賬号 并選擇彈窗 通過在result 中多加屬性 來驗證判斷
				let resultSet = dealData.getData(0);
				resultSet.loginFlag = loginFlag;
				resultSet.userMessage = personData.userMessage[0];
				// 必須使用render發出resultset數組來接收資料 不然會報錯
				res.render('index', resultSet);
			} else {
				let loginFlag = {
					idFlag: false,
					pwd: false
				};
				let resultSet = dealData.getData(0);
				resultSet.loginFlag = loginFlag;
				res.render('index', resultSet);
			}
		} else {
			let loginFlag = {
				idFlag: false,
				pwd: false
			};
			let resultSet = dealData.getData(0);
			resultSet.loginFlag = loginFlag;
			res.render('index', resultSet);
		}
	}, 10)
});

// app.get('/game-frist.html', function(req, res) {
// 	// 獲得get請求的參數 這是express參數key(屬性名)
// 	// console.log(req.query.id);
// 	res.render('game-frist');
// });

app.get('/page*', function(req, res) {
	let path = parseInt(url.parse(req.url).pathname.substr(5));
	// 同樣構成了異步
	let resultset = dealData.getData(path);

	if (typeof path == 'number') {
		// 因該是因為浏覽器内置的cookie什麼的
		// 這裡需要停一段時間
		setTimeout(function() {
			let loginFlag = {
				idFlag: false,
				pwd: false
			};
			let resultSet = dealData.getData(path);
			resultSet.loginFlag = loginFlag;
			res.render('index', resultSet);
		}, 30)
		// res.render('index', resultset);
	} else {
		// res.render('index', dealData.getData(0));
	}
});

app.listen(9999, function() {
	console.log('伺服器正在監聽用戶端的請求...');
})
           
nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

  這個地方如果不使用setTimeout(function() {

})

  這個異步方法等待, 同時在前面加上對資料庫的通路, 就不會出現資料通路錯為的問題

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

  就會出現問題,而直接寫對資料庫的通路就會出現問題

gif動圖示範
nodejs 實戰項目學習 資料庫通路結果為undefined express ejs
資料庫通路

  資料庫通路使用mysql 的子產品使用前記得從cnpm 或者從 npm中下載下傳下來

var mysql = require('mysql');

var connection = mysql.createConnection({
	host: 'localhost',
	port: 3306,
	user: 'root',
	password: '123',
	database: 'testdata'
})

connection.connect();

connection.query('select * from users',function(error, results) {
	console.log(results);
})

connection.end();
           

  資料庫結構

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs

  通路結果

nodejs 實戰項目學習 資料庫通路結果為undefined express ejs
資源定位

名稱:

Day9_13實戰項目.rar(還在稽核) …

https://github.com/xiaoJianghello/Day9_21Testproject

繼續閱讀