【问题标题】:What is causing my request to timeout?是什么导致我的请求超时?
【发布时间】:2018-08-09 02:46:53
【问题描述】:

我正在尝试创建一个允许用户上传 csv 文件的路由,然后将该文件异步解析为 Json 并为每一行实例化一个模型。我曾尝试使用承诺来这样做,但函数请求一直超时,我看不到它在哪里中断。这是代码(/app/index):

const csv=require('csvtojson');
const multer  = require('multer');
const upload = multer().single(); 

router.post('/distributor/:id/upload', (req,res) => { 
  return new Promise((resolve, reject) => {
    upload(req,res,function(err){
      if(err !== null) return reject(err);
      resolve();
    });
  })
  .then((req, res) => {
    return csv()
    .fromString(req.body.toString('utf8'))
    .on('json', (item) => { 
      item.distributor_id = req.params.id 
      Product
      .forge(item.body)
      .save()
      .then((product) => {
        res.json({id: product.id});
      })
      .catch((error) => {
        console.error(error);
        return res.sendStatus(500);
      })
    })
    .on('done', () => { 
      console.log('done parsing'); 
      resolve();
    });
  }) 
})

当我将文件发布到此路由时,heroku 日志的输出如下:

(node:49) UnhandledPromiseRejectionWarning: Unhandled promise rejection 
(rejection id: 2): undefined
2018-08-09T03:57:17.240599+00:00 app[web.1]: (node:49) [DEP0018] 
DeprecationWarning: Unhandled promise rejections are deprecated. In the 
future, promise rejections that are not handled will terminate the Node.js 
process with a non-zero exit code.
2018-08-09T03:57:47.205596+00:00 heroku[router]: at=error code=H12 
desc="Request timeout" method=POST path="/api/distributor/1/upload" host=fba- 
prof-prods.herokuapp.com request_id=40e1864b-fa71-49aa-8fdf-cedb1752edef 
fwd="73.92.68.83" dyno=web.1 connect=1ms service=30284ms status=503 bytes=0 
protocol=https

如果您能指出任何可以正确完成类似操作的资源/示例(处理上传和异步解析大型 csv 文件),我也将不胜感激。我不知道如何做到这一点,似乎找不到任何好的资源!谢谢。

【问题讨论】:

  • 你需要拒绝/解决你的承诺 - new Promise((resolve, reject)) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 好的,我改变了它,但我仍然得到相同的结果。我认为之前我的一些回调没有返回值,但我认为现在它们都有。
  • 如果文件很大,网络可能会超时。您可以在路由中增加网络超时 req.setTimeout(600 * 1000)。这个会存活 10 分钟
  • 谢谢你,@Sandeep。我在这方面取得了一些进展,但我仍然不确定如何以可以解析的形式获取文件。我在这里有更新的详细信息link

标签: node.js express promise es6-promise multer


【解决方案1】:

你需要做这样的事情:

function uploadAsync(req,res){
    return new Promise((resolve, reject) => {
         upload(req,res,function(err){
             if(err !== null) return reject(err);
             resolve();
         });
    });
}

注意resolve()。这是这里的关键,因为你没有对这个 Promise 做任何事情。

【讨论】:

  • 好的,我尝试将其合并。我还更新了我当前的日志输出!
  • 这里的东西太多了……你能不能把它清理一下,这样你就可以一步一步去。就像清理.then((req, res) => { 和console.log 中的所有内容一样。在链接其余部分之前,让我们确保该部分按预期工作。
  • 好主意@Akrion。我摆脱了 .then((req, res) => { 调用中的所有内容并将其替换为 console.log(req)。它没有记录任何内容,我仍然得到相同的输出和超时错误,所以我猜一个问题必须在第一个承诺中?
  • 所以这是因为你没有向resolve() 传递任何东西,所以你可以在then 中得到一些东西......在upload(req,res,function(err) 函数中放置一个console.log(res)看看是否打印出任何东西......然后只将你需要的东西作为参数传递给resolve(),然后你应该在then中得到它。请参阅 Promise.resolve 文档:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 谢谢你,@Akrion。我在这方面取得了一些进展,但我仍然不确定如何以可以解析的形式获取文件。我在这里有更新的详细信息link
猜你喜欢
  • 2017-07-24
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 2011-05-29
  • 2012-09-18
  • 2011-09-18
  • 2020-10-12
相关资源
最近更新 更多