await导致的请求失败404

新手上路,请多包涵

有个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')]);

都可以正常返回结果。。

有没有遇到过类似问题的小伙伴

阅读 1.9k
1 个回答

Promise.all() 是不能保证其执行的各个 promise 间的顺序。
如果你需要顺序,应该按顺序一个一个的 await。比如

await this.axios.post(`/getRoleFromUserGuid`, {"uGuid": userGuid});
this.axios.get('/login/syncUsers')
注:没仔细看代码,但感觉应该是 Promise.all() 执行顺序的问题。试试看。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题