JavaScript及Node.js中Promise用法与数据库按需查询问题
问题A解答
你说的myResolve不是不存在的函数,它是Promise构造函数注入到执行器中的内置方法,你只是给它起了myResolve这个变量名而已,换成resolve、successCallback这类任意名字都能正常运行。
Promise本质是用来标记异步操作状态的容器,总共有三种状态:未完成(pending)、成功(fulfilled)、失败(rejected),状态一旦变更就固定不会再变。你调用myResolve的本质是告诉Promise:当前异步操作已经成功完成,把我传给myResolve的参数作为结果存起来,并且触发后续.then绑定的回调。
如果你不调用myResolve,Promise就会一直停留在pending状态,.then里的回调永远不会被触发,res.end永远不会执行,浏览器收不到服务器的返回结果,自然会一直处于加载状态。
问题B解答
你最初的写法是在全局作用域直接创建Promise,所以程序一启动就会立刻执行数据库连接和查询逻辑,和有没有请求进来完全没关系。
你第一次修改的封装代码有问题:你直接返回同步变量myResult,但数据库查询是异步操作,函数返回的时候查询还没执行完,myResult还是undefined,自然没法调用.then。你后续改成返回Promise的版本是完全正确的,直接在请求回调里调用这个函数即可,示例如下:
var http = require('http'); var mysql = require('mysql'); var con = mysql.createConnection({ host: "localhost", user: "root", password: "******", database: "heroes" }); function connectToDB() { return new Promise(function(myResolve, myReject) { // 操作失败的时候调用myReject把错误抛出去,方便后续捕获处理 con.connect(function(err) { if (err) return myReject(err); con.query("SELECT id, name FROM heroes", function (err, result, fields) { if (err) return myReject(err); myResolve(JSON.stringify(result)); }); }); }); } http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'application/json'}); // 每次收到请求再调用函数触发查询 connectToDB() .then(result => res.end(result)) .catch(err => { // 错误处理逻辑 res.statusCode = 500; res.end(JSON.stringify({error: err.message})) }); }).listen(8080);
补充优化建议:不用每次请求都调用con.connect,可以全局复用连接,或者使用mysql的连接池来管理连接,避免连接耗尽的问题。
内容的提问来源于stack exchange,提问作者RT.
相关产品推荐
相关产品推荐

