首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

node中异步操作问题(一)

node开发中,很多操作都是异步的,比如我们连接数据库,查询数据.首先,我们需要等待数据连接成功,然后要等待查询成功,也就是说在我们把从数据库查询到的结果返回到用户之前,至少需要经过两次回调.

回调函数除了剥夺了我们使用return和throw这些关键字,这种回调黑洞还会造成代码的可读性不强.代码复杂.为了解决这个问题,es6时候,出现了promise对象,es7中出现了async/await.这两种结合,很好的解决了上面的问题.

首先,我们了解promise对象.

promise对象是用来传递异步操作的消息,它代表了未来才会知道结果的事件(即程序中的异步操作).promise对象状态不受外界影响,它有三个状态,pending(进行中),resolved(已完成),rejected(已失败).它的状态只取决于异步操作的结果,并且一旦改变,就会不再修改.promise改变的情况有两种:

pending(进行中)==>resolved(已完成)

pending(进行中)==>rejected(已失败)

只要任何一种情况出现,promise的状态就已经定型,这时候,我们再对promise对象进行回调就即刻得到它的状态结果,(这时候的回调就是同步的).这种机制与事件是完全不同的,事件的特点是,如果错过了,再去监听,是获取不到结果的.

promise的使用很简单.

var promise =new promise(function(resolve,reject)){

if(success){

resolve()

}else{

reject()

}

}

promise.then((result) => { })

.catch((reason) => {});

从代码可以看出promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve方法和reject方法.resolve状态将prome对象状态从pending(进行中)改变为resolved(已完成),reject状态将prome对象状态从 pending(进行中)改变为rejected(已完成). promise.then和catch是处理成功和失败的方法.在then中我们可以return另一个promise,而在catch中,我们可以对多个异常更精准的捕获.

知道了promise的使用方法,我们针对文章开头讲的问题,来用promise就行优化.

首先,我们创建config.json文件,来同意保存mysql的配置

{

"mysql": {

"host": "",

"user": "",

"port": 3306,

"password": "",

"database": "",

"charset": "UTF8MB4_GENERAL_CI"

}

}

然后创建mysqlServer.js文件.来配置mysql自动连接池,等等公共方法

var express = require('express');

var router = express.Router();

var mysql = require('mysql');

var bodyParser = require("body-parser");

var config = require("../config.json");

var pool = mysql.createPool(config.mysql);

router.use(bodyParser.json({

limit: "20000 kb"

}));

router.use(bodyParser.urlencoded({

parameterLimit: 1000,

limit: '50mb',

extended: false

}));

module.exports = pool;

接下来我们在写接口的js中,使用promise优化自动连接池和sql语句执行的回调.

//处理连接数据库

const connectionMysql = (sql) => {

return new Promise(function(resolve, reject) {

mysql.getConnection(function(err, connection) {

if (err) {

} else {

resolve(sqlSever(connection, sql))

}

});

});

}

//处理sql语句

const sqlSever = (connection, sql) => {

return new Promise(function(resolve, reject) {

connection.query(sql, function(err, rows, fields) {

if (err) {

console.log(err)

} else {

resolve(rows);

}

})

});

}

处理完之后,我们在写接口的时候,可以直接这样用

//使用Promise对异步处理

router.get('/getList', function(req, res, next) {

var sql = 'select title from test';

connectionMysql(sql)

.then((result) => {

var json = {

code: 200,

data: result

}

res.send(json);

})

.catch((reason) => {});

});

这样代码是不是简洁多了,当然,上面的两个方法是对所有接口公用的,我们可以单独提出来,当做共有方法.

Promise也有一些缺点,首先.当我们启动Promise之后,中途无法取消,其次,如果不设置回调函数,异常只会在Promise内部抛出,最后当处于pending(进行中)我们无法知道进度.

es7中的async/await是基于Promise来实现的,它同Promise一样都是非阻塞的,用来异步代码看起来想同步,但是async/await代码更简洁,对与异常处理也更加灵活,另外它能把Promise中的嵌套平铺避免了深层嵌套.(我们上面的代码就是深层嵌套).

下一篇文章,我们继续了解node中异步操作中另一种解决办法async/awai.

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180105G0O64300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com