当http请求的参数需要借用到上一次http请求参数的结果时,利用promise或者利用更方便简洁的async/await

本文探讨了在需要连续发起多次HTTP请求,且后续请求依赖于前一次请求结果的情况下,如何利用Promise的then方法及async/await语法来简化代码,提高代码的可读性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时候会遇到一些情况,比如在点击事件触发的时候,我需要发送两次或以上的 http 请求,而这两次请求时相关的,即第二次 http 请求的参数需要携带第一次 http 请求的结果,这种时候,一般的处理如下:

function f() {
    $.get('xxx1.json', function(res1) {
        var m = res1.id // 假设返回一个对象,该对象的属性id,需要作为参数再次发送请求
        $.post('xxx2.json', {id: m}, function(res2) {
            console.log(res2) // 这里返回的 res2 就是我想要的结果
        })
    })
}

上述写法,很麻烦,如果遇到两次以上的请求时,会容易出错。

这时候,我们可以利用 promise 的 then 的写法进行封装:

function f1() {
    return new Promise((resolve, reject) => {
        // 这里用 setTimeout 模拟 http 请求
        setTimeout(() => {
            var result = {
                id: 10
            }
            
            resolve(result)  // 假设这个 result 就是第一次请求返回的结果,这个结果的 id 值将作为参数传递给第二次请求
        }, 2000)
    })
}

function f2(param) {
    // 这里的 param 参数就是第一次 http 请求的结果(result.id的值),这里将作为第二次 http 请求的参数
    return new Promise((resolve, reject) => {
        // 这里用 setTimeout 模拟 http 请求
        setTimeout(() => {
            var n = 20
            resolve(n)  // 假设这里的 n 的值就是第二次请求利用 result.id 作为实参的结果
        }, 1000)
    })
}

// promise.then 的写法
f1().then(res1 => {
    var id = res1.id
    f2(id).then(res2 => {
        console.log(res2)
    })
})

上述方法同样可以用 async/await 实现:


// async/await 的写法
async function test() {
    var s1 = await f1() // s1 表示第一次 http 返回的结果
    var s2 = await f2(s1.id) // s2 表示利用第一次 http 返回的结果(result.id),作为第二次 http 请求的参数,而得到的结果
    console.log(s2)
}
test()

如此看来,利用 async/await 写法,使代码结构和逻辑更清晰、易读。

补充实例:对于看不懂的朋友,我写了一份实例,如下:

getInfo = () => {
    return request({
        method: 'get',
        url: '/info',
        header: {
            "Content-type": "application/json",
        }
    })
}

getDetails = (id) => {
    return request({
        method: 'get',
        data: {
            userId: id
        },
        url: '/details',
        header: {
            "Content-type": "application/json"
        }
    })
}

function f1() {
    return new Promise((resolve, reject) => {
        getInfo().then(res => {
            var res = {
                id: 1,
                name: 'sonovabitch'
            }
            resolve(res)
        })
    })
}

function f2(param) {
    return new Promise((resolve, reject) => {
        getDetails(param).then(res => {
            var res = {
                name: 'bitch',
                age: 99
            }
            resolve(res)
        })
    })
}

// 第一种写法

f1().then(res1 => {
    f2(res1.id).then(res2 => {
        console.log(res2.name) // 'bitch'
    })
})

// 第二种写法
async function test() {
    var s1 = await f1()
    var s2 = await f2(s1.id)
    console.log(s2.name) // 'bitch'
}

 

<think>嗯,我现在要帮这个大三的学生设计一个耗材共享管理系统,作为数据库原理的课程设计。首先,我需要理清楚整个系统的架构和需要实现的功能。用户提到后端用Node.js + Express + MySQL,前端用HTML/CSS/JavaScript,这应该是比较典型的MEAN/MERN栈,不过这里用的是MySQL而不是MongoDB,所以应该是类似MEEN(MySQL, Express, EJS, Node.js)的结构?不过前端可能不用EJS,直接用纯HTML。 首先,系统的大致功能应该是耗材的管理,包括添加、查询、借用、归还等。可能需要用户注册登录,权限管理,比如普通用户和管理员的不同权限。然后数据库设计方面,需要考虑哪些实体和关系。比如用户表、耗材表、借用记录表等等。需要确定各个表的字段,主键外键关系。 接下来是后端部分,用Express搭建RESTful API,处理前端发来的请求,连接MySQL数据库。这里可能需要用到的Node.js模块有express、mysql2或者knex.js这样的库来操作数据库。同要考虑路由的设计,比如用户相关的路由,耗材管理的路由,借用归还的路由等。中间件如body-parser用来解析请求体,cors处理跨域问题,还有身份验证的中间件,比如JWT。 前端部分用纯HTML、CSS和JS的话,可能需要用到一些前端框架或者库来简化开发,比如Bootstrap做样式,或者Axios处理HTTP请求。不过用户没有提到使用前端框架,所以可能用原生JS。前端页面需要包括登录注册界面,耗材列表展示,借用归还的操作界面,管理后台等。 然后,具体步骤的话,可能需要先设计数据库,创建表结构,然后搭建后端API,再开发前端页面,最后联调测试。需要确保前后端的数据交互正确,比如前端通过AJAX调用后端的API接口,获取JSON数据并动态渲染到页面上。 可能遇到的问题包括数据库连接配置,如何处理异步操作,比如Node.js的异步IO,防止回调地狱,使用async/await或者Promise。还有安全方面的问题,比如SQL注入,需要参数化查询或者使用ORM避免。用户认证方面,如何安全存储密码,使用哈希加盐,JWT的生成和验证等。 另外,耗材的状态管理,比如是否可借用,库存数量,借用记录的状态(已归还,未归还)。可能需要定任务或者触发器来处理逾期未归还的情况,但课程设计可能不需要这么复杂。 测试方面,可以用Postman测试API接口是否正常工作,再在前端进行功能测试。部署的话,可能本地运行,或者使用云服务器,但课程设计可能只需要本地演示。 需要给用户提供一个清晰的步骤指南,包括环境搭建,依赖安装,代码结构,关键代码示例,比如创建Express应用,连接数据库,定义模型,实现CRUD操作,路由处理,前端页面的交互逻辑等。 可能还需要考虑数据验证,比如用户输入是否符合要求,后端如何处理错误,返回合适的HTTP状态码和错误信息。前端如何提示用户操作结果,比如借用成功或失败的原因。 最后,文档的编写,包括系统设计文档,数据库ER图,API接口文档,用户手册等,作为课程设计的一部分可能需要这些材料。 总结下来,整个流程应该是:需求分析 -> 数据库设计 -> 后端开发 -> 前端开发 -> 测试调试 -> 文档编写。每个步骤需要详细说明,并提供代码示例和注意事项,确保学生能够顺利实现系统的基本功能。</think>好的,我将分步骤为你介绍如何搭建这个基于Node.js + Express + MySQL的“耗材共享管理系统”,并提供关键实现要点。 ### 一、系统架构设计 ``` 前端:HTML + CSS + JavaScript │ ▼ 后端:Node.js + Express(RESTful API) │ ▼ 数据库:MySQL ``` ### 二、开发环境搭建 1. 安装VS Code扩展: - MySQL(数据库管理) - REST Client(API测试) - Prettier(代码格式化) 2. 安装依赖: ```bash npm init -y npm install express mysql2 cors body-parser npm install nodemon --save-dev ``` ### 三、数据库设计(示例) ```sql -- 用户表 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, role ENUM('user', 'admin') DEFAULT 'user' ); -- 耗材表 CREATE TABLE supplies ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, quantity INT DEFAULT 0, location VARCHAR(100), status ENUM('可用', '已借出', '维护中') DEFAULT '可用' ); -- 借用记录表 CREATE TABLE borrow_records ( id INT PRIMARY KEY AUTO_INCREMENT, user_id INT, supply_id INT, borrow_date DATE, return_date DATE, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (supply_id) REFERENCES supplies(id) ); ``` ### 四、后端核心实现 1. 创建`app.js`: ```javascript const express = require('express'); const mysql = require('mysql2'); const cors = require('cors'); const app = express(); // 数据库连接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'yourpassword', database: 'supply_db', waitForConnections: true, connectionLimit: 10 }); app.use(cors()); app.use(express.json()); // 示例API:获取所有耗材 app.get('/api/supplies', (req, res) => { pool.query('SELECT * FROM supplies', (err, results) => { if(err) return res.status(500).json({ error: err.message }); res.json(results); }); }); const PORT = 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); ``` ### 五、前端关键功能实现 1. 耗材列表展示(HTML): ```html <div id="supply-list"> <table> <thead> <tr> <th>名称</th> <th>数量</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody id="supply-data"></tbody> </table> </div> <script> // 获取耗材数据 async function loadSupplies() { const response = await fetch('http://localhost:3000/api/supplies'); const data = await response.json(); const tbody = document.getElementById('supply-data'); tbody.innerHTML = data.map(item => ` <tr> <td>${item.name}</td> <td>${item.quantity}</td> <td>${item.status}</td> <td> <button onclick="borrowItem(${item.id})">借用</button> </td> </tr> `).join(''); } </script> ``` ### 六、核心功能实现要点 1. 用户认证: - 使用JWT实现登录验证 - 密码存储使用bcrypt加密 2. 关键业务逻辑: ```javascript // 借用操作示例 app.post('/api/borrow', async (req, res) => { const { userId, supplyId } = req.body; // 事务处理 const connection = await pool.promise().getConnection(); try { await connection.beginTransaction(); // 检查库存 const [rows] = await connection.query( 'SELECT quantity FROM supplies WHERE id = ? FOR UPDATE', [supplyId] ); if(rows[0].quantity < 1) { throw new Error('库存不足'); } // 新库存 await connection.query( 'UPDATE supplies SET quantity = quantity - 1 WHERE id = ?', [supplyId] ); // 创建借用记录 await connection.query( 'INSERT INTO borrow_records SET ?', { user_id: userId, supply_id: supplyId, borrow_date: new Date() } ); await connection.commit(); res.json({ success: true }); } catch (error) { await connection.rollback(); res.status(400).json({ error: error.message }); } finally { connection.release(); } }); ``` ### 七、安全增强措施 1. SQL注入防护: ```javascript // 使用参数化查询 pool.query('SELECT * FROM users WHERE username = ?', [username], ...); ``` 2. API安全: - 添加请求频率限制 - 敏感操作记录日志 - 启用HTTPS(部署) ### 八、测试建议 1. 使用Postman测试API 2. 编写单元测试(Jest框架) 3. 压力测试(Apache Bench) ### 九、扩展功能建议 1. 耗材二维码管理 2. 借用到期提醒(邮件/短信) 3. 数据可视化报表 4. 多仓库库存管理 建议先从核心功能(用户管理、耗材列表、借用归还)开始实现,逐步添加扩展功能。开发过程中注意版本控制(Git),合理规划项目目录结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值