【问题标题】:Async Method Timeout in NodejsNodejs中的异步方法超时
【发布时间】:2020-05-30 03:31:36
【问题描述】:

我正在下载一个文件,有时文件可能很大并且超时时间不够。超时时,我想取消下载过程,因为即使我收到超时错误,它也会继续处理文件并给出以下异常

_http_outgoing.js:470 抛出新的 ERR_HTTP_HEADERS_SENT('set'); ^

错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头 在 ServerResponse.setHeader (_http_outgoing.js:470:11)

这是我的异步方法

router.get('/api/files/GetFile', urlencodedParser, (req, res) => { 

 return new Promise(function (resolve, reject) {    
    (async function () {
      try {

        var folderName = "File_" + moment().format('DD-MM-YYYY HH_mm_ss');
        await routerFile.CreatePdfZip(req.query.VoucherCodes, req.query.AppNames, folderName);

        var fullzipPath = './FilesToDownload/' + folderName + '.zip';

        zipFolder('./FilesToDownload/' + folderName, './FilesToDownload/' + folderName + '.zip', function (err) {
          if (err) {
            return reject(err);
          } else {

            console.log('zip created');
            rimraf('./FilesToDownload/' + folderName, function () {
              console.log("folder has been deleted");
            });

            fs.readFile(fullzipPath, (err2, zipData) => {
              if (err2) reject(err2);

              const base64 = zipData.toString('base64');
              res.setHeader('Content-type', 'application/zip');
              res.type('zip');
              res.end(base64, 'binary');
              console.log('EXCELLENT');
            });
          }
        });       
      } catch (error) {    
        return reject(error);
      }
    })();
    }).catch(error => {
      console.log(error);
      res.send(error);
   });
});

错误发生在res.setHeader('Content-type', 'application/zip');

PS:路由器变量来自const router = express.Router();

这里是超时设置

const app = express();
app.use(timeout('2s'));
app.use(bodyParser());
app.use(haltOnTimedout);
app.use(cookieParser());
app.use(haltOnTimedout);

function haltOnTimedout(req, res, next) {
  if (!req.timedout)
    next();
  else {
    console.log('TIMEOUT.----------------------------------------------');    
  }
}

我在这里做错了什么?或者有没有更好的方法来设置超时并取消下载过程

PS:CreatePdfZip 方法需要时间。

【问题讨论】:

    标签: node.js asynchronous promise settimeout cancellation


    【解决方案1】:

    为避免此错误,您可以检查response是否已发送,如果未发送则仅发送响应(但并不能真正解决/取消下载处理)

    ...
    fs.readFile(fullzipPath, (err2, zipData) => {
        if (err2) reject(err2);
    
        if (!res.headersSent) {
            const base64 = zipData.toString('base64');
            res.setHeader('Content-type', 'application/zip');
            res.type('zip');
            res.end(base64, 'binary');
            console.log('EXCELLENT');
        }
    });
    ...
    

    Doc Link

    【讨论】:

      猜你喜欢
      • 2018-05-21
      • 2014-12-05
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 2020-05-13
      • 1970-01-01
      相关资源
      最近更新 更多