【问题标题】:Socket.io and Async Not Returning ValuesSocket.io 和 Async 不返回值
【发布时间】:2020-06-11 07:31:26
【问题描述】:

我有一个async 客户端函数,它返回是否使用用户名。我正在使用 socket.io 发送数据包,但我无法找出问题所在。

这是功能(浏览器):

let socket = io();
async function createAccount(username, password){
    socket.emit('create account', {username:username, password:password});

    let res;

    await socket.on('create account return', (data) => {
        res = data.failed;
    });
    return res;
};

这是我的测试脚本,如果用户名有效则记录true,否则记录false

createAccount('bagel03', '12345').then((val)=>console.log(val));

相反,我总是得到未定义,但如果我将 createAccount 函数中的 return 语句更改为:

return true;

它可以工作并记录true

我是async await 的新手(这是我的第一个项目),网上没有任何帮助。有什么问题?

编辑: 这是服务器代码(Node.js):

const io = require('socket.io')(server,{ pingTimeout: 4000, pingInterval: 4000 })

io.sockets.on('connect',  socket =>{
    //account stuff
    socket.on('create account',  data =>{
        if(!isUsernameTaken(data.username)){
            id = addAccount(data);
            socket.emit('create account return',{failed:false})
        }else socket.emit('create account return', {failed:true})

    });
});

【问题讨论】:

  • 你能把服务器上的代码放上去吗?您在 socket.io 中声明事件的位置?
  • 是的,我把它省略了,因为它不太有用,但可以肯定

标签: javascript node.js socket.io async-await es6-promise


【解决方案1】:

我认为您没有以正确的方式使用 Websocket 对象。
每次调用createAccount 时,都会向'create account return' 事件添加一个处理程序。例如,如果您调用createAccount 3 次,您在'create account return' 上有3 个处理程序。

事件也是async,每当它们被触发时,都会调用事件处理程序。
这是您可以使用它的最简单的方法,但最好将其包装在一个类中

let socket = io();
function createAccount(username, password){
    socket.emit('create account', {username:username, password:password});

};

function myHandler(data) {
   console.log(data.failed);
}

socket.on('create account return', myHandler);

【讨论】:

    【解决方案2】:

    您不能在偶数侦听器上使用await。如果你想写你的createAccount 以便被await 调用,你只需要让它返回一个Promise。比如:

    let socket = io();
    function createAccount(username, password) {
      return new Promise((resolve, reject) => {
        socket.emit('create account', {username:username, password:password});
    
        socket.once('create account return', (data) => resolve(data.failed));
      });
    };
    

    【讨论】:

    • 请注意,这仍然会每次都添加一个新的侦听器,甚至在再次调用时再次尝试解析先前的承诺。
    • 感谢@CherryDT 指出。我改变了答案:现在使用socket.once 而不是socket.on
    猜你喜欢
    • 1970-01-01
    • 2015-12-03
    • 2020-09-21
    • 1970-01-01
    • 2015-11-08
    • 2020-09-03
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多