1. 程式人生 > 實用技巧 >Backtrader中文筆記之Order Management and Execution

Backtrader中文筆記之Order Management and Execution

Express簡介

  • Express框架特性

    • 提供了方便簡潔的路由定義方式
    • 對獲取HTTP請求引數進行了簡化處理
    • 對模板引擎支援程度高,方便渲染動態HTML頁面
    • 提供了中介軟體機制有效控制HTTP請求
    • 擁有大量第三方中介軟體對功能進行擴充套件
  • Express框架初體驗

    • 專案資料夾下下載 npm install express
    • 引入express框架 const express = require('express');
    • 建立網路伺服器 const app = express();
    • 監聽埠 app.listen(3000);
    • 路由定義 send()方法功能
      • send方法內部會檢測響應內容的型別 Request Method
      • send方法會自動設定http狀態碼 Status Code
      • send方法會幫我們自動設定響應的內容型別及編碼 Content-Type
    • 當訪問不存在的路由時,頁面提示 Cannot GET /lists
// 引入express框架
const express = require('express');
// 建立網路伺服器
const app = express();

app.get('/', (req, res) => {
    res.send('Hello Express');
});
app.get('/list', (req, res) => {
    res.send({
        name: 'sunny',
        age: 20
    });
})
//監聽埠
app.listen(3000);
console.log('網站伺服器啟動成功');

中介軟體

  • 中介軟體概念

    • 中介軟體就是一堆方法,可以接收客戶端發來的請求、可以對請求做出響應,也可以將請求繼續交給下一個中介軟體繼續處理。
    • 中介軟體主要由兩部分構成,中介軟體方法以及請求處理函式。
    • 中介軟體方法由Express提供,負責攔截請求,請求處理函式由開發人員提供,負責處理請求。
      • app.get('請求路徑', '處理函式') 接收並處理get請求
      • app.post('請求路徑', '處理函式') 接收並處理post請求
  • 設定多箇中間件 next引數

    • 可以針對同一個請求設定多箇中間件,對同一個請求進行多次處理。
    • 預設情況下,請求從上到下依次匹配中介軟體,一旦匹配成功,終止匹配。
    • 可以呼叫next方法將請求的控制權交給下一個中介軟體,直到遇到結束請求的中介軟體。
app.get('/request', (req, res, next) => {
    req.name = 'sunny';
    next();
});
app.get('/request', (req, res) => {
    res.send(req.name);
})
  • app.use 中介軟體用法
    • app.use 匹配所有的請求方式,可以直接傳入請求處理函式,代表接收所有的請求。
    • app.use 第一個引數也可以傳入請求地址,代表不論什麼請求方式,只要是這個請求地址就接收這個請求。
app.use((req, res, next) => {
    console.log(req.url);
    next();
});
app.use('/admin', (req, res, next) => {
    console.log(req.url);
    next();
});
  • 中介軟體應用
    • 路由保護,客戶端在訪問需要登入的頁面時,可以先使用中介軟體判斷使用者登入狀態,使用者如果未登入,則攔截請求,直接響應,禁止使用者進入需要登入的頁面。
    • 網站維護公告,在所有路由的最上面定義接收所有請求的中介軟體,直接為客戶端做出響應,網站正在維護中。
    • 自定義404頁面
// 網站公告
// app.use((req, res, next) => {
//     res.send('當前網路正在維護!');
// });
app.use('/admin', (req, res, next) => {
    let IsLogin = false;
    IsLogin? next(): res.send('請您登陸後再訪問');
});
app.get('/admin', (req, res) => {
    res.send('您已經登入,可以訪問頁面');
})
// 為客戶端響應404狀態碼以及提示資訊
app.use((req, res, next) => {
    res.status(404).send('當前訪問頁面不存在!');
});
  • 錯誤處理中介軟體
    • 在程式執行的過程中,不可避免的會出現一些無法預料的錯誤
    • 比如檔案讀取失敗,資料庫連線失敗
    • 錯誤處理中介軟體是一個集中處理錯誤的地方。
app.get('/index', (req, res, next) => {
    // throw new Error('程式發生了未知錯誤');
    fs.readFile('/demo.txt', 'utf8', (err, result) => {
        if(err != null){
            next(err);
        }else{
            res.send(result);
        }
    });
});
// 錯誤處理中介軟體
app.use((err, req, res, next) => {
    res.status(500).send(err.message);
});
  • 捕獲錯誤
    • 在node.js中,非同步API的錯誤資訊都是通過回撥函式獲取的
    • 支援Promise物件的非同步API發生錯誤可以通過catch方法捕獲
    • try catch 可以捕獲非同步函式以及其他同步程式碼在執行過程中發生的錯誤,但是不能其他型別的API發生的錯誤
app.get('/index', async (req, res, next) => {
    try {
        await readFile('./aaa.js');
    } catch (ex) {
        next(ex);
    }
});
// 錯誤處理中介軟體
app.use((err, req, res, next) => {
    res.status(500).send(err.message);
});

Express框架請求處理

  • 構建模組化路由
    • 建立app.js
    • 建立模組路由home.js
    • 建立模組路由admin.js
// 引入express框架
const express = require('express');
// 建立網路伺服器
const app = express();
// home路由模組
const home = require('./route/home.js');
app.use('/home', home);
// admin路由模組
const admin = require('./route/admin.js');
app.use('/admin', admin);
// 錯誤處理中介軟體
app.use((err, req, res, next) => {
    res.status(500).send(err.message);
});
//監聽埠
app.listen(3000); 
console.log('網站伺服器啟動成功');
// 引入express框架
const express = require('express');
// 建立一級路由
const home = express.Router();
// 建立二級路由
home.get('/index', (req, res) => {
    res.send('歡迎來到部落格展示頁面');
});
module.exports = home;
// 引入express框架
const express = require('express');
// 建立一級路由
const admin = express.Router();
// 建立二級路由
admin.get('/login', (req, res) => {
    res.send('歡迎來到部落格登入頁面');
});
module.exports = admin;
  • GET引數的獲取
    • Express框架中使用req.query即可獲取GET引數,框架內部會將GET引數轉換為物件並返回。
    • 位址列回車 http://localhost:3000/index?name=sunny&age=90
    • 輸出 {"name":"sunny","age":"90"}
app.get('/index', (req, res) => {
    res.send(req.query);
});
  • POST引數的獲取
    • 下載第三方包:npm install body-parser
    • Express中接收post請求引數需要藉助第三方包 body-parser
    • extended: false,則會呼叫系統模組querystring對引數格式進行處理
// 引入express框架
const express = require('express');
// 引入body-parser模組
const bodyParser = require('body-parser');
// 建立網路伺服器
const app = express();
// 攔截所有請求
// 配置body-parser模組
// extended: false 方法內部使用querystring模組處理請求引數的格式
// extended: true 方法內部使用第三方模組qs處理請求引數的格式
app.use(bodyParser.urlencoded({ extended: false }));
// 接收請求
app.post('/add', (req, res) => {
    // 接收請求引數
    res.send(req.body);
}) 
//監聽埠
app.listen(3000); 
console.log('網站伺服器啟動成功');
<form action="http://localhost:3000/add" method='post'>
    <input type="text" name='username'>
    <input type="password" name='password' >
    <input type="submit">
</form>
  • Express路由引數
    • 位址列http://localhost:3000/index/025/sunny/19
    • 輸出{"id":"025","name":"sunny","age":"19"}
    • 如果不傳遞引數,那麼將匹配不到路由
app.get('/index/:id/:name/:age', (req, res) => {
    res.send(req.params);
})
  • 靜態資源訪問
    • app.use()攔截所有請求
    • 通過Express內建的express.static可以方便地託管靜態檔案
    • 例如img、CSS、JavaScript檔案等
// 引入express框架
const express = require('express');
const path = require('path');
// 建立網路伺服器
const app = express();
// 靜態資源訪問
app.use(express.static(path.join(__dirname, 'public')));
//監聽埠
app.listen(3000); 
console.log('網站伺服器啟動成功');

express-art-template模板引擎

  • 模板引擎
    • 為了使art-template模板引擎能夠更好的和Express框架配合,模板引擎官方在原art-template模板引擎的基礎上封裝了express-art-template
    • 使用npm install art-template express-art-template命令進行安裝
const express = require('express');
const path = require('path');
const app = express();
// 當渲染字尾為art的模板時 使用express-art-template
app.engine('art', require('express-art-template'));
// 設定模板存放目錄
app.set('views', path.join(__dirname, 'views'));
// 渲染模板時不寫字尾 預設拼接art字尾
app.set('view engine', 'art');
app.get('/index', (req, res) => {
   // 渲染模板
   // 拼接模板路徑
   // 拼接模板字尾
   // 模板與資料匹配拼接
   // 將拼接結果響應給了客戶端
   res.render('index', {
       msg: 'message'
   });
}); 
app.get('/list', (req, res) => {
    res.render('list', {
        name: 'sunny',
        age: 18
    });
});
//監聽埠
app.listen(3000); 
console.log('網站伺服器啟動成功');
  • app.locals 物件 公共程式碼
    • 將變數設定到app.locals物件下面,這個資料在所有的模板中都可以獲取到
const express = require('express');
const path = require('path');
const app = express();
app.engine('art', require('express-art-template'));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'art');
app.locals.user = [{
    name: 'Tom',
    age: 18
},{
    name: 'Jerry',
    age: 20
}]
app.get('/index', (req, res) => {
   res.render('index', {
       msg: '首頁'
   });
}); 
app.get('/list', (req, res) => {
    res.render('list', {
        msg: '列表頁'
    });
});
app.listen(3000); 
console.log('網站伺服器啟動成功');
<!-- index.art -->
<p>{{msg}}</p>
<ul>
    {{each user}}
    <li>
        <p>{{$value.name}}</p>
        <p>{{$value.age}}</p>
    </li>
    {{/each}}
</ul>
<!-- list.art -->
<p>{{msg}}</p>
<ul>
    {{each user}}
    <li>
        <p>{{$value.name}}</p>
        <p>{{$value.age}}</p>
    </li>
    {{/each}}
</ul>