【问题标题】:NodeJS - How to deal with UnhandledPromiseRejectionWarning?NodeJS - 如何处理 UnhandledPromiseRejectionWarning?
【发布时间】:2020-02-16 16:43:06
【问题描述】:

我对 Node JS 还很陌生,所以我有点挣扎。

我正在尝试使用他们的 API 从我的 Node Js 代码中读取 google drive 的文件。

我有以下代码

router.get('/', function (req, res, next) {

  var pageToken = null;
// Using the NPM module 'async'
async.doWhilst(function (callback) {
  drive.files.list({
    q: "mimeType='image/jpeg'",
    fields: 'nextPageToken, files(id, name)',
    spaces: 'drive',
    pageToken: pageToken
  }, function (err, res) {
    if (err) {
      // Handle error
      console.error(err);
      callback(err)
    } else {
      res.files.forEach(function (file) {
        console.log('Found file: ', file.name, file.id);
      });
      pageToken = res.nextPageToken;
      callback();
    }
  });
}, function () {
  return !!pageToken;
}, function (err) {
  if (err) {
    // Handle error
    console.error(err);
  } else {
    // All pages fetched
  }
})

  res.render('index', { title: 'Express' });

});

当我发送获取请求时,上面的代码给了我以下错误

(node:13884) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
    at E:\nodejs\newcelebapi\routes\index.js:49:17
    at E:\nodejs\newcelebapi\node_modules\googleapis-common\build\src\apirequest.js:43:53
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:13884) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:13884) [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.

问题出在下面一行

  res.files.forEach(function (file) {

我已尽我所能,放弃理解问题。

你能帮我解决这个问题吗?

谢谢!

【问题讨论】:

  • JS 在编写 async 包后继续前进,并且它已经支持 promises 和原生 async/await 有一段时间了 - 我强烈建议不要使用该包,除非你对 JS 有足够的了解,能够解释为什么原生 async/await 或 Promise 不够好(可以肯定地说,现在情况并非如此)。

标签: javascript node.js google-drive-api


【解决方案1】:

根据this example in the doc,您想使用:

res.data.files.forEach(...)

不是:

res.files.forEach(...)

而且,一旦你解决了这个问题,你就会遇到另一个问题,因为你在错误的地方调用了res.render()。而且,当您解决该问题时,您将在 Google 回调中重新定义 res 时遇到问题,这将隐藏您需要为 res.render() 提供的更高级别的 res

我强烈建议您不要在此处使用async 库。这里似乎不需要它,它只会使事情复杂化。而且,如果您在协调异步操作方面确实需要帮助,那么 Promise 是一种现代方式。

你没有展示你试图对结果文件做什么(除了记录它们),但这里有一个简单的实现:

router.get('/', function (req, res, next) {
  var pageToken = null;
  drive.files.list({
    q: "mimeType='image/jpeg'",
    fields: 'nextPageToken, files(id, name)',
    spaces: 'drive',
    pageToken: pageToken
  }).then(response => {
      let files = response.data.files;
      files.forEach(file => console.log('Found file: ', file.name, file.id))
      res.render('index', { title: 'Express' });
  }).catch(err => {
      console.log(err);
      res.sendStatus(500);
  });
});

请注意,我将 drive.files.list() 中的参数命名为 response 而不是 res,因此我可以从 router.get() 回调和 responsedrive.files.list() 回调中访问 res。你给他们两个同名res,这意味着你不能访问同名的router.get()参数。

【讨论】:

  • 太棒了!它奏效了。我想我需要复习一下我对 Node Js 的了解才能理解最后一点。但是,我明白你的意思。我赞成答案,我想我太新了,不能这样做,但它被记录下来了!这是我收到的消息“感谢您的反馈!声望低于 15 人的投票将被记录,但不要更改公开显示的帖子得分。”
  • @ThikkaReya - 由于您是新手,因此您还没有足够的声誉来投票,但既然您提出了这个问题,您可以通过单击复选标记“接受”最能回答您问题的答案在答案的左边。这既会向社区表明您的问题已得到解答,也会因在此处遵循正确的程序而为您赢得一些声誉积分。
猜你喜欢
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2019-05-13
  • 2017-10-05
相关资源
最近更新 更多