Javascript 使用Express放置路由后未执行代码

Javascript 使用Express放置路由后未执行代码,javascript,node.js,express,Javascript,Node.js,Express,我在上收听的聊天事件!叠加chat我想执行一些代码。我想在得到这一信息后实现的是: 获取用户 检查用户是否有足够的货币 从用户处扣除货币 触发我的react应用程序的套接字事件 直到最后一点,一切似乎都很顺利。在我的终端中显示,我的用户扣除了货币(在我的代码中称为“kluiten”),但它后面的所有代码都没有执行 require('dotenv').config(); const PORT = process.env.PORT || 9000; class TwitchAPI { co

我在
上收听的聊天事件!叠加
chat我想执行一些代码。我想在得到这一信息后实现的是:

  • 获取用户
  • 检查用户是否有足够的货币
  • 从用户处扣除货币
  • 触发我的react应用程序的套接字事件
直到最后一点,一切似乎都很顺利。在我的终端中显示,我的用户扣除了货币(在我的代码中称为“kluiten”),但它后面的所有代码都没有执行

require('dotenv').config();
const PORT = process.env.PORT || 9000;

class TwitchAPI {
  constructor({io}) {
    this.io = io;
    this.client = new tmi.client(options);

    this.client.connect();

    this.handleOverlayRequest = this.handleOverlayRequest.bind(this);
    this.handleChatMessage = this.handleChatMessage.bind(this);

    this.client.on('chat', this.handleChatMessage);
  }

  handleChatMessage (channel, userstate, message) {
   if(message === '!overlay') this.handleOverlayRequest(channel, userstate);
  }

  async handleOverlayRequest (channel, userstate) {
    const requiredKluiten = 5;
    const rawFoundUser = await fetch(`http://localhost:${PORT}/api/users/${userstate.username}`);
    const foundUser = await rawFoundUser.json();

    if(foundUser.instakluiten >= requiredKluiten) {
      this.client.action(channel, `${userstate[`display-name`]}, you've got enough instakluiten for this.`);

      const method = `PUT`;
      const payload = { 'requiredKluiten': requiredKluiten };
      const body = JSON.stringify(payload);
      const headers = { 'Content-Type': `application/json; charset=utf-8` };

      const result = await fetch(`http://localhost:${PORT}/api/users/${userstate.username}/decrementKluiten`, { method, body, headers });
      console.log(result);
    }
  }
}

module.exports = TwitchAPI;
然后我有一个快速路由器:

const express = require('express');
const userController = require('../controllers/userController');

const router = express.Router();

router.route('/users/:username/decrementKluiten').put(userController.decrementKluiten);
router.route('/users/:username').get(userController.getUser);
router.route('/overview').get(userController.getOverview);

module.exports = router;
这样可以确保货币被扣除。我现在坚持的是,在这一切发生之后,我无法在获取之后再执行任何代码。我发现,虽然我可以通过解析路径中的承诺来执行代码,但这感觉真的很脏,并且会弄乱我的拆分文件:

router.route('/users/:username/decrementKluiten').put((req, res) => {
 userController.decrementKluiten(req, res).then(x => {
  console.log(x);
 });
});
有没有一种方法可以等待我的PUT发生,并在它发生后仍然执行代码

编辑

userController.js

const {findChattersPerRole, getUserByUsername, decrementKluiten} = require('../actions');
const find = require(`lodash/find`);
const fetch = require(`isomorphic-fetch`);
const parseJSON = response => response.json();

module.exports = {
  getUser: (req, res) => {
    const username = req.params.username;
    findChattersPerRole()
      .then(chattersPerRole => {
        const wantedUser = find(chattersPerRole, { username });
        getUserByUsername(wantedUser.username)
          .then(foundUser => {
            if (foundUser) {
              res.send(foundUser);
            } else {
              res.send(`No user has been found`);
            }
          });
      });
  },
  getOverview: (req, res) => {
    fetch(`https://tmi.twitch.tv/group/user/instak/chatters`)
    .then(parseJSON)
    .then(r => {
      return res.json(r);
    }).catch(err => {
      console.log(err);
    });
  },
  decrementKluiten: (req, res) => {
    decrementKluiten(req.params.username, req.body.requiredKluiten);
  }
}
actions.js

(因为这包含了很多代码,所以我尝试只包含本文的相关部分,数据库调用是使用Sequelize.js完成的)


问题可能是您没有响应
/users/:username/decrementtkluiten
路由中的HTTP请求。要解决此问题,请将
userController.js
-文件中导出的
decrementKluiten
方法更改为:

decrementKluiten: (req, res) => {
  decrementKluiten(req.params.username, req.body.requiredKluiten)
    .then(() => res.sendStatus(200))
    .catch(() => res.sendStatus(500));
}

一些不相关的指针使代码更具可读性,因为您已经在代码的某些部分使用了
async
函数,但在其他部分,您直接与promission接口

userController.js的导出部分可以利用
async
函数:

module.exports = {
  getUser: async (req, res) => {
    try {
      const username = req.params.username;
      let chattersPerRole = await findChattersPerRole();
      let wantedUser = find(chattersPerRole, { username });
      let foundUser = await getUserByUsername(watnerUser.username);
      if (foundUser) {
        res.status(200).send(foundUser);
      } else {
        res.status(404).send('No user has been found');
      }
    } catch (e) {
      res.sendStatus(500);
    }
  },
  getOverview: async (req, res) => {
    try {
      let r = (await fetch('https://tmi.twitch.tv/group/user/instak/chatters')).json();
      res.json(r);
    } catch (e) {
      res.sendStatus(500);
    }
  },
  decrementKluiten: async (req, res) => {
    try {
      await decrementKluiten(req.params.username, req.body.requiredKluiten);
      res.sendStatus(200);
    } catch (e) {
      res.sendStatus(500);
    }
  }
}
我还添加了错误处理功能,以防出现问题,服务器会以
500内部服务器错误
状态代码进行响应

通过您的
TwitchAPI
课程中的这些行判断:

const rawFoundUser = await fetch(`http://localhost:${PORT}/api/users/${userstate.username}`);
const foundUser = await rawFoundUser.json();
我假设您已尝试执行
const foundUser=wait fetch(“…”).json()
。这会导致错误,但如果将等待表达式括在括号中,则可以在同一行上调用返回值的方法和属性,如下所示:

const foundUser = await (await fetch('...')).json()`
如果其方法不返回承诺(即同步),或者您希望访问属性,则可以执行以下操作:

const something = (await doSomethingAsync()).someMethod()
const somethingElse = (await doSomethingAsync()).property

我还注意到,您在大多数字符串中使用模板文本(反勾号,
`
),而不进行任何模板插值,这可以简单地用
'
(单引号)或
(双引号)替换.

如果您可以包含来自
userController
模块的相关代码,那就太好了。@Svenskunganka我添加了最相关的部分。在
userController.js
-文件中,导出的
decrementKluiten
方法,如果您将其代码替换为
decrementKluiten(req.params.username,req.body.requiredKluiten)。然后(()=>res.sendStatus(200)).catch(()=>res.sendStatus(500))
,那么它能工作吗?我不知道我们是否可以为此打开一个聊天室,我想我们可能需要进行一些调试,我有一些无关的指针给你。该死的,这很有效。明智的做法是分离sendStatus。我知道在发送状态之前我必须进行干预,但没有想到这样做,尽管这相当容易。Y你应该把它添加为答案,这样我就可以批准它,因为这对我很有帮助。我仍然希望得到一些反馈,尽管是无关的指针!很好,很高兴它成功了!我将用一些指针为你撰写一个答案,并在几分钟后发布它:)当我尝试您较短的获取foundUser的方法时,foundUser记录为挂起的承诺,它只在我将它们拆分时才起作用。@Kevin哦,是的,你说得对,我的错!响应的
json()
方法实际上是异步的,并返回一个承诺。我已更新了我的答案以反映这一点。抱歉!:)
const something = (await doSomethingAsync()).someMethod()
const somethingElse = (await doSomethingAsync()).property