is it possible to freeze while waiting for a socke

2019-03-07 04:43发布

问题:

socket.on('res', function(data) {  
    peanuts = data;
});


abc = function(){
    peanuts = [];
    socket.emit('req', index);
    while (!peanuts[0]) {};    
    return peanuts[0];
};

like this, infinite loop.

abc = function(){
peanuts = [];
var intr = setInterval(function(){
    if (peanuts[0]) {
        clearInterval(intr);            
    };
}, 100)
return peanuts[0];

};

like this, it returns "peanuts[0]" before the "peanuts = data;"

pls help me.


socket.emit('req', index, function(answer) {
    console.log(answer);
});  
console.log('duck');

found that it could sending with acknowledgement.. but i want console.log(answer) run before console.log('duck')


OK,Actually my code is like this..

function poo() {
    var x = a() & b();
    /*
    blablabla.....
    */
    return z;
}

function a() {
    socket.emit('req', index, function(answer) {
        var temp = answer
    });  
    return temp;
}

console.log(poo());

And if I use that ‘sync style’(but not sync), I need to rewrite function poo,right? That's why I want sync, for some reason, I can only rewrite function a, so, is it possible to check as the condition of while instead of emit with acknowledgement or using listener?

Like this?

function a() {
    socket.emit('req', index);
    while (!socket.???) {
    };
    return socket.????;
}

回答1:

Is it possible to freeze while waiting for a socket?

No, it is not possible in Javascript. You can't "block" the interpreter while waiting for a network event to arrive. Because of the event-driven design of Javascript, if you do a while() loop that tries to wait for the value, the while() loop will block the event loop so that the result can never get processed. Thus, you end up with a deadlock and essentially a loop that never completes.

I really want sync, is it impossible in this case?

It is impossible. The event-driven nature of Javascript and socket.io requires you to use that event-driven architecture, not a blocking, synchronous architecture. To use a blocking, synchronous architecture, you will need a different language and environment that supports threads and blocking I/O (like Java, for example).

The operation is asynchronous so you have to program your function to properly return value asynchronously. The function should either return a promise that resolves when the value arrives or the function should take a callback that you will call when the value arrives. Or, you can just use the callback already built into .emit() directly to process the result in the callback (as shown below).

The calling code then needs to adapt to use the asynchronous result. That's how async programming works in Javascript. To use asynchronous operations, you have to learn how to program asynchronously.

You need to write event-driven code, not blocking code. Set up event listeners or promises and then continue your process when that event fires or the callback is called. It's hard to make a concrete suggestion for how your code should work because you are showing mostly pseudo-code, not real code.

For more detail on returning an async value, you can see this canonical answer on the topic.


FYI, if you're trying to use socket.io in a mode that's kind of like request/response where you want a specific response from a request message sent, then socket.io has a feature for that using a callback on the .emit() (the server has to cooperate to make this work):

socket.emit('req', index, function(answer) {
    // put code here that uses the answer
});  

This is how you do async response handling in Javascript. You don't write sequential, synchronous functions. You use an event driven callback.