简体   繁体   中英

Function return the result getting from an socket.on (socket.io)

I'm a newbie with socket.io. I encounter some trouble dealing with the asynchronous of socket.on and wonder is there a workaround or some way to make the whole function blocks for the socket.on

I am developing an API to fetch data from MongoDB. And call those API in react frontend. I am recently trying to do as following:

// frontend (onClick function)
const handleOnClick = () => {
    const data = api();
    // do the work
}


// API
const api = () => {
var value;

    // ask for data
    socket.emit("ask-for-data");

    // get respond from database
    socket.on("get-response", (data) => {
        value = data;                       //<- value is correct right here
    });

    //respond from API
    return { value };                       //<- value is undefined

I want to let the whole function return the data fetch by socket.io. However, I tried adding async-await to the API function and it turns out of no use.

// frontend (onClick function)
const handleOnClick = async () => {
    const data = await api();
    // do the work
}


// API
const api = async () => {
var value;

    // ask for data
    socket.emit("ask-for-data");

    // get respond from database
    await socket.on("get-response", (data) => {
        value = data;                       //<- value is correct right here
    });

    //respond from API
    return { value };                       //<- value is undefined

So is there any way to make sure I can return the value I got from socket.on? I know that socket.on is handle as an asynchronous function and the API function will return way before the socket io finishes their tasks. BTW, API and handleOnClick are stored in different js files. Thanks for your time!

socket.on() is not an async: this means that the execution flow will proceed without waiting for any get-response event and your value variable will be undefined .

Try wrapping your api function in a Promise which resolves when you on get-response , something like:

const api = function() {
  return new Promise(function(resolve, reject) {
    socket.emit("ask-for-data");
    socket.on("get-response", (data) => {
      resolve(data);
    })
  });
}

and then

const data = await api();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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