gpt4 book ai didi

node.js - 在 Node js 中正确使用 async wait

转载 作者:太空宇宙 更新时间:2023-11-04 00:14:50 24 4
gpt4 key购买 nike

为了克服 JavaScript 中的回调 hell ,我尝试使用 SQLServer 过程中编写的遗留代码中的异步等待。但我不确定我的代码是否可以正确编写。

我的第一个困惑点是当异步函数返回时,它应该返回resolve()作为 bool 值,还是只返回reject并用try-catch处理?

这是我的代码片段。请纠正我正确的方向。

apiRoutes.js

app.route('/api/dansok/cancelDansok')
.post(dansokCancelHandler.cancelDansok);

dansokCancelController.js

const sequelize = models.Sequelize;
const jwt = require('jsonwebtoken');

async function jwtAccessAuthCheck(accessToken) {
if (!accessToken) {
return Promise.reject('Empty access token');
}

jwt.verify(accessToken,"dipa",function(err){
if(err) {
return Promise.reject('TokenExpiredError.');
} else {
return Promise.resolve();
}
});
}

async function checkFeeHist(dansokSeqNo) {
let feeHist = await models.FeeHist.findOne({
where: { DansokSeqNo: dansokSeqNo}
});
return !!feeHist;
}

async function getNextDansokHistSerialNo(dansokSeqNo) {
....
}

async function getDansokFee(dansokSeqNo) {
....
}

async function doCancel(dansokSeqNo) {
try {
if (await !checkFeeHist(dansokSeqNo)) {
log.error("doCancel() invalid dansokSeqNo for cancel, ", dansokSeqNo);
return;
}
let nextDansokSerialNo = await getNextDansokHistSerialNo(dansokSeqNo);
await insertNewDansokHist(dansokSeqNo, nextDansokSerialNo);
await updateDansokHist(dansokSeqNo);
await updateVBankList(dansokSeqNo, danokFee.VBankSeqNo);
await getVBankList(dansokSeqNo);
} catch (e) {
log.error("doCancel() exception:", e);
}
}

exports.cancelDansok = function (req, res) {
res.setHeader("Content-Type", "application/json; charset=utf-8");
const dansokSeqNo = req.body.DANSOKSEQNO;
const discKindCode = req.body.HISTKIND;
const worker = req.body.PROCWORKER;
const workerIp = req.body.CREATEIP;
const accessToken = req.headers.accesstoken;

//check input parameter
if (!dansokSeqNo || !discKindCode || !worker || !workerIp) {
let e = {status:400, message:'params are empty.'};
return res.status(e.status).json(e);
}

try {
jwtAccessAuthCheck(accessToken)
.then(() => {
log.info("jwt success");
doCancel(dansokSeqNo).then(() => {
log.info("cancelDansok() finish");
res.status(200).json({ message: 'cancelDansok success.' });
});
});
} catch(e) {
return res.status(e.status).json(e);
}
};

最佳答案

您需要重写jwtAccessAuthCheck(accessToken),以便它跟踪其嵌套任务的结果。在您编写的代码中:

// Code that needs fixes!
async function jwtAccessAuthCheck(accessToken) {

// This part is fine. We are in the main async flow.
if (!accessToken) {
return Promise.reject('Empty access token');
}

// This needs to be rewritten, as the async function itself doesn't know anything about
// the outcome of `jwt.verify`...
jwt.verify(accessToken,"dipa",function(err){
if(err) {
// This is wrapped in a `function(err)` callback, so the return value is irrelevant
// to the async function itself
return Promise.reject('TokenExpiredError.');
} else {
// Same problem here.
return Promise.resolve();
}
});

// Since the main async scope didn't handle anything related to `jwt.verify`, the content
// below will print even before `jwt.verify()` completes! And the async call will be
// considered complete right away.
console.log('Completed before jwt.verify() outcome');

}

更好的重写是:

// Fixed code. The outcome of `jwt.verify` is explicitly delegated back to a new Promise's
// `resolve` and `reject` handlers, Promise which we await for.
async function jwtAccessAuthCheck(accessToken) {
await new Promise((resolve, reject) => {

if (!accessToken) {
reject('Empty access token');
return;
}

jwt.verify(accessToken,"dipa",function(err){
if(err) {
reject('TokenExpiredError.');
} else {
resolve();
}
});

});

// We won't consider this async call done until the Promise above completes.
console.log('Completed');

}

也适用于此特定用例的替代签名:

// Also works this way without the `async` type:
function jwtAccessAuthCheck(accessToken) {
return new Promise((resolve, reject) => {
...
});
}
<小时/>

关于您的 cancelDansok(req, res) 中间件,由于 jwtAccessAuthCheck 保证返回 Promise (您将其设为异步函数),因此您还需要直接处理其返回的 Promise。没有 try/catch 可以处理此异步任务的结果。

exports.cancelDansok = function (req, res) {

...

jwtAccessAuthCheck(accessToken)
.then(() => {
log.info("jwt success");
return doCancel(dansokSeqNo);
})
.then(() => {
log.info("cancelDansok() finish");
res.status(200).json({ message: 'cancelDansok success.' });
})
.catch(e => {
res.status(e.status).json(e);
});

};
<小时/>

我强烈建议阅读一些与 Promise 相关的文章来掌握它的窍门。它们非常方便且功能强大,但与其他 JS 模式(异步回调、try/catch...)混合时也会带来一些麻烦。

关于node.js - 在 Node js 中正确使用 async wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47630266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com