微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Repl.it 未处理的承诺拒绝

如何解决Repl.it 未处理的承诺拒绝

我想在 Repl.it 上为我的游戏实现一个基本的排行榜,所以我创建了一个 node.js 后端。这是我在后端的:

const express = require('express');
const Client = require('@replit/database');
const db = new Client();

const cors = require('cors');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');

const server = express();
server.use(cors());
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: false }));

server.get('/',(req,res) => {
  res.send('Online');
});

server.post('/leaderboard',async (req,res) => {
  const m = await db.get('leaderboard');
  m.push({
    score: parseInt(req.body.score,10),time: new Date()
  });
  m.sort((a,b) => b.score - a.score);
  await db.set('leaderboard',m);
    
  res.send(req.body);
});

server.get('/leaderboard',res) => {
  const leaderboard = await db.get('leaderboard');
  res.json(leaderboard);
});

server.listen(3000);

但是每当我尝试 POST 时,我都会收到以下错误

(node:344) UnhandledPromiseRejectionWarning: TypeError: 无法读取 null 的属性 'push'

(node:344) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。这个错误要么是因为在没有 catch 块的情况下抛出了异步函数,要么是因为拒绝了一个没有用 .catch() 处理过的承诺。要在未处理的承诺拒绝时终止节点进程,请使用 CLI 标志 --unhandled-rejections=strict(请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝编号:1)

(node:344) [DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止 Node.js 进程。

如果我尝试 GET,res 会返回 null - 可能是因为我在执行 POST 时没有推送任何内容

为什么会发生这种情况,我该如何解决

解决方法

如何处理承诺拒绝?

您收到 UnhandledPromiseRejectionWarning 是因为您无法捕获异步路由中发生的错误。请参阅快速 error handling 指南。您需要附加某种错误处理程序 -

var bodyParser = require('body-parser')

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(...)

// error handler
app.use(function (err,req,res,next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

app.post(...)

app.get(...)

...

next()next(err) 的调用表明当前处理程序已完成以及处于何种状态。 next(err) 将跳过链中所有剩余的处理程序,除了那些设置为处理错误的处理程序...

为什么承诺会被拒绝?

发生错误是因为 mnullnull 没有 .push 方法。调用 null.push(...) 会引发错误,导致承诺因此错误而被拒绝。

为什么 mnull 值?

我不知道 repl.it API,但大概 db.get('leaderboard') 没有价值,这就是 m 收到 null 响应的原因。你可以尝试像这样修复它

server.get('/leaderboard',async (req,res) => {
  const leaderboard = (await db.get('leaderboard')) || [] // <-
  res.json(leaderboard);
});

server.post('/leaderboard',res) => {
  const m = (await db.get('leaderboard')) || [] // <-
  // ...
});

在结果中添加 ... || [] 表示如果 db.get 的响应为假(null 为假),请改用空数组 []

复制/数据库

set(key: string,value: any): promise<void>
get(key: string): promise<any | null>
get(key: string,{raw: true}): promise<string | null>

set 使用 JSON.stringify 自动对值进行编码。

get 旨在检索 JSON 字符串并自动对其进行解码。如果未找到字符串,则返回一个 null 值,这正是您遇到的情况。

注意,您可以使用 db.get(someKey,{raw: true}) 获取原始字符串,跳过 JSON.parse 步骤。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。