简体   繁体   English

在 JavaScript 中等待 Socket.io 响应

[英]Wait for Socket.io response in JavaScript

I have been working on this problem for a long while, but still can't seem to figure it out.我一直在研究这个问题很长一段时间,但似乎仍然无法弄清楚。 I have a client (or rather a proxy in this case) that should provide a function that returns a userlist.我有一个客户端(或者在这种情况下是代理),它应该提供一个返回用户列表的函数。 The userlist exists on a server, and should be served on request via socket.io.用户列表存在于服务器上,应通过 socket.io 请求提供服务。

Here is what I currently have:这是我目前拥有的:

as the client:作为客户:

 async function getUserList(){ return new Promise( (resolve) => { socket.on('connect', async function (data) { socket.emit('getData', 'users'); socket.on('data', async function (response) { var response = await response; if (response) { resolve(response); } else { reject(response); } }); }); }); }; function getUserList1(){ getUserList().then(function(response){ return response; }).catch(function(error){console.log(error);}) }

or updated:或更新:

 getUserList = async function() { const getUserList1 = () => new Promise(resolve => { socket.on('connect', data => { socket.emit('getData', 'users'); socket.on('data', response => { resolve(response); }); }); }); console.log('Receiving data'); const users = await getUserList1(); // Waits here until it is done. console.log('Data received: ', JSON.stringify(users)); return users; }; var newUsers = getUserList(); console.log(newUsers)

and as the server:并作为服务器:

 var users = { Foreador: '1234', mudito: '1234', troll: '1234', josocxe: '1234' }; var subjects = ["Primer tema", "Segundo tema"]; io.on('connection', function(socket){ console.log('a user connected'); socket.on('disconnect', function(){ console.log('user disconnected'); }); socket.on('getData', function(data){ console.log("the request received:", data) if (data == "users"){ io.emit('data', users); console.log("sending back users") }}); socket.on("sendData", function(data){ console.log("the data received:", data) users = data console.log("Final users: ", users) }) }); http.listen(3000, function(){ console.log('listening on *:3000'); });

The code itself works, but if I call getUserList1 I receive first undefined and then later I can log the result.代码本身有效,但如果我调用 getUserList1,我首先收到 undefined 然后我可以记录结果。 I know that its against the asynchronous nature of JS, but I want to directly receive the result (that is the requirement of the exercise and I dont really see any other way to do it).我知道它违背了 JS 的异步特性,但我想直接接收结果(这是练习的要求,我真的没有看到任何其他方法可以做到)。 I have so far tried do achieve this with callbacks as well as promises, but did not succeed.到目前为止,我已经尝试通过回调和承诺来实现这一点,但没有成功。 So, does anybody know how I could halt the code execution until I have received the response from the server?那么,有没有人知道我如何在收到服务器的响应之前停止代码执行? I hope I have explained myself and thanks for your help!我希望我已经解释了自己,并感谢您的帮助!

Yeah是的

First of all, the point of using socket is that you would have a reactive software that can listen to changes.首先,使用套接字的目的是您将拥有一个可以侦听更改的反应式软件。

So, whenever there is a change, you can do something about it.所以,只要有变化,你就可以做些什么。

Look an example:看一个例子:

function initializeSocket() {
    const socket = ...;
    socket.on('connect', data => {
      socket.emit('getData', 'users');
      socket.on('data', newUsers => 
        renderUsers(newUsers)
      );
    });
  });
}

function renderUsers(users) {
  .
  . // Here could handle some render logic
  .
}

That's the way the event driven architecture works, simple as that.这就是事件驱动架构的工作方式,就这么简单。

But, if you need to wait for some async call from the server, I would recommend you to provide an endpoint in your server for it, so you could call it and wait for the response.但是,如果您需要等待来自服务器的一些异步调用,我建议您在服务器中为其提供一个端点,以便您可以调用它并等待响应。

Like this simple express example:就像这个简单的快递示例:

app.get('/users', (req, res, next) => 
  res.json(users)
)

and on the client side:在客户端:

const users = await fetch(api_url + '/users')

What you need is to use async / await to store your result in a variable.您需要的是使用async / await将结果存储在变量中。 You are already doing it in some parts of your code so you are familiar.您已经在代码的某些部分这样做了,所以您很熟悉。 You could use an async IIFE to make your current scope able to use the await keyword.您可以使用async IIFE使您当前的范围能够使用await关键字。

Below I've made an example with a simplified version of your getUserList function and a single variable which calls the value with the await keyword.下面我用简化版本的getUserList函数和一个使用await关键字调用值的单个变量制作了一个示例。 This will halt the execution of the rest of the function scope until getUserLists resolves.这将停止执行其余函数作用域,直到getUserLists解析为止。 Now you can use the result from the getUserList function in the user variable.现在您可以在user变量中使用getUserList函数的结果。

(async function() {

  const getUserList = () => new Promise(resolve => {
    socket.on('connect', data => {
      socket.emit('getData', 'users');
      socket.on('data', response => {
        resolve(response);
      });
    });
  });

  const users = await getUserList(); // Waits here until it is done.
  // Continue all your code after this.

}());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM