有个node express下的项目,在处理每次前端请求的时候都有一段验证代码,用来验证请求合法性,如下,我们引入了jwtFilter 对jwt进行验证:
var self = {
init: function (options) {
self.o = options || {};
self.add(jwtFilter).add(xssFilter)
return self.run;
},
add: function (fn) {
self.filterList.push(fn);
return self;
},
runNext: function (o, req, res) {
if (self.o.next && self.o.currentFunction < self.filterList.length) {
self.filterList[self.o.currentFunction](o, req, res, function(){
self.o.currentFunction++;
if (!!res.err && !!res.err["309"]) {
self.o.doNext = false;
}
self.runNext(self.o, req, res);
});
} else {
self.complete();
}
},
run: function (req, res, next) {
self.o.req = req, self.o.res = res, self.o.next = next, self.o.doNext = true, self.o.currentFunction = 0;
if (self.o.next && self.o.currentFunction < self.filterList.length) {
self.runNext(self.o, req, res);
}
},
complete: function () {
if (self.o.doNext)
self.o.next();
},
o: {
req: {},
res: {},
next: {},
doNext: true,
currentFunction: 0
},
filterList: [],
};
module.exports = self.init;
jwtFilter.js 部分代码如下,其中getLoginiat是异步函数用来从redis读取一个时间:
module.exports = async (op, req, res, callback)=> {
let jwtObj;
var o = op || {};
// if not login url, jwt always required
if(req.url !== `/${app_name}/login/authenticate` && req.url !== `/${app_name}/login/authenticateForClient`) {
try {
jwtObj = jwtUtil.jwtVerify(req.cookies[jwt_name]);
} catch (e) {
responseHandler(res, {code: 308}, null);
}
if (jwtObj && jwtObj.dbUrl) {
let login_iat = await getLoginiat(jwtObj.uGuid);
if (jwtObj.iat != login_iat) {
res.err[309] = codeMapping[309];
responseHandler(res, {code: 309}, null);
callback();
}
callback();
}else{
res.err[301] = codeMapping[301];
responseHandler(res, {code: 301}, null);
callback();
}
} else {
callback();
}
}
function getLoginiat(uguid) {
return redisClient.get(uguid).then(function (result) {
return result;
});
}
前端通过axios发起如下两个request,第一个请求在执行到await getLoginiat(jwtObj.uGuid)之后会返回主程序 runNext来执行第二个request(/syncUsers),这是没有问题的,await会主动让出线程,主程序执行完之后会继续执行await后面的代码。
Promise.all([this.axios.post(`/getRoleFromUserGuid`, {
"uGuid": userGuid}), this.axios.get('/login/syncUsers')]);
现在有个问题是这样执行之后,/syncUsers总是返回404错误,感觉是在第一个request /getRoleFromUserGuid 执行到await getLoginiat(jwtObj.uGuid)的时候跳出来执行/syncUsers,之后又分别执行await后续的代码,导致了这个问题,试过单独执行一个request是可以正常返回结果的
Promise.all([this.axios.post(`/getRoleFromUserGuid`, {"uGuid": userGuid})]);
或
Promise.all([this.axios.post(this.axios.get('/login/syncUsers')]);
都可以正常返回结果。。
有没有遇到过类似问题的小伙伴
Promise.all()
是不能保证其执行的各个 promise 间的顺序。如果你需要顺序,应该按顺序一个一个的 await。比如