Node js async.series无法使用Express应用程序--响应发生得太早

Node js async.series not working with Express app --- response happening too soon

本文关键字:响应 应用程序 太早 Express async js series Node      更新时间:2023-10-04

我有一个Node js Express应用程序,我在那里设置来自许多不同地方的cookie(服务器、Twitter、另一个数据库等)。这些都需要串联发生。为了避免回调噩梦,我尝试使用Async.js。但是,在Async.series调用完成之前,响应一直在发送。如何确保async.series完成,然后调用res.redirect?

使用异步调用模块

// OTHER CODE
accountCookies(req, res, next);  // THE MODULE WITH ASYNC
res.redirect(302, 'https://' + req.host + '/account');

异步模块

module.exports = function (req, res, next) {
req.appVariables.error = null;
// Required modules
var async = require(__dirname + '/utilities-----async.js'); // Utility for controlling node's asynchronous behavior
var userSessionObject = {};
// ...OTHER MODULES
// Cookie values set by the server
var cookieValuesSetByTheServer = function(req, res, next, userSessionObject, callback) {
    userSessionObject.STUFF = STUFF;
    logs.dev('cookieValuesSetByTheServer');
    setTimeout(function(){callback(req.appVariables.error, '1');}, 3000);
};
// Cookie values from Twitter
var cookieValuesFromTwitter = function(req, res, next, userSessionObject, callback) {
    userSessionObject.moreSTUFF = moreSTUFF;
    logs.dev('cookieValuesFromTwitter')
    callback(req.appVariables.error, '2');
};
// Cookie values from User Database
var cookieValuesFromUserDatabase = function(req, res, next, userSessionObject, callback) {
    userSessionObject.otherSTUFF = otherSTUFF;
    logs.dev('cookieValuesFromUserDatabase');
    setTimeout(function(){callback(req.appVariables.temporarilyUnavailableCalled, '3');}, 6000);
};
// Call all functions in Series
async.series([
    function(callback){
        cookieValuesSetByTheServer(req, res, next, userSessionObject, callback);
    },
    function(callback){
        cookieValuesFromTwitter(req, res, next, userSessionObject, callback);
    },
    function(callback){
        cookieValuesFromUserDatabase(req, res, next, userSessionObject, callback);
    }
], function(err, results){
    if ( err == null ) {
        logs.dev(results);
        return true;
    }
    else {
        logs.dev(err);
        return false;
    }
});

};

您需要等待async.series完成后才能发送响应。通常的方法是传递一个回调函数:

accountCookies(req, res, next, function theCallbackFunction(success) {
  res.redirect(302, 'https://' + req.host + '/account');
});
// in your async module
module.exports = function (req, res, next, theCallbackFunction) {
  ...
  async.series([ ... ], function(err, results) {
    if ( err == null ) {
      logs.dev(results);
      theCallbackFunction(true);
    } else {
      logs.dev(err);
      theCallbackFunction(false);
    }
  });
};

换句话说:不能在异步函数中使用return将返回值传递回调用者。

您可以尝试用中间件函数替换next回调,该函数只执行res.redirect,然后传递请求。

accountCookies(req, res, function(req, res, next) {
    res.redirect(302, 'https://' + req.host + '/account');
    next();
});