关于JavaScript中实现异步处理、同步等待是否可以?

时间:2021-03-05 23:41:41
我目前有个需求,是客户端JS和服务器端的之间通过websocket通信(服务器端不是Web服务器,也不可能配置为Web服务器):客户端发送一个操作请求消息、服务器端接到消息之后处理并返回一个结果。

由于JS是单线程顺序处理、而网络通信又是异步的,怎么样我才能让客户端的JS程序在发送一个命令之后、等待服务器返回结果之后再往下执行(类似C++/Java中的WaitForEvent)?

用个栗子说明下:

var _socket;

function init () {
// 创建一个Socket实例,尝试连接服务器
_websocket = new WebSocket('ws://127.0.0.1:' + _serverPort); 

// 握手成功
_websocket.onopen = function (e) {
_isConnected = true;
};

// 监听消息
_websocket.onmessage = function(event) {
_isResponded = true;
                        _respData = event.data;
}; 

// 监听Socket的关闭
_websocket.onclose = function(event) { 
socket = null;
alert("连接关闭!");
}; 
}

function waitForResp() {
       while(!_isResponded) {};       //这样写是不行的,因为JS不能响应socket的onmessage事件了!!!
}

function getServerTime() {
      var time;
       _websocket.send("{get_time}");     //1
       waitForResp();                                   //2
       //此处处理响应数据                           //3
       return time;                                         //4
}

上面的代码,我是想调用getServerTime()等得到服务器响应之后才返回,也就是说该函数本身希望是阻塞(同步)的。然后,等待函数 waitForResp()该怎么实现才能保证在JS等待的同时还能响应onmessage()事件呢?

谢谢!

18 个解决方案

#1


顺便说一句!

一般人们会建议我,在send一个命令之后马上返回、然后等响应时间触发之后再处理(使用回调函数)、也就是说异步执行,让页面步等待。

但是我希望的是用户在一个操作完成之前、不能进行其他操作,所以希望每个JS函数都是同步(阻塞)的。不希望用户发送一个命令之后就不管结果、页面还能接受用户其他操作。

#2


用回调函数
在getServerTime接收一个callback,在onmessage时调用

#3


引用 2 楼 Free_Wind22 的回复:
用回调函数
在getServerTime接收一个callback,在onmessage时调用


即使这样做,函数getServerTime()还是会在send()之后马上返回!
而我的要求是等处理完服务器的响应数据之后、函数getServerTime()才返回。

#4


js没有阻塞功能,ajax同步也会造成浏览器无响应

代码结构要换一下。或者用promise, jscex改写一下

#5


为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。

#6


用promise只能解决“发送消息”和“处理响应”之间的同步关系,但是不能阻止调用函数直接返回。

比如:

       function fnSend(){
           var p = new Promise() ;
           alert("this is send!") ;  
           p.done() ;
           return p ; 
         }
       function fnHandler(){
          var p = new Promise() ;
          alert("this is response handler!") ;
          p.done() ;
          return p ;
       } 

function test() {
    fnSend().then(fnHandler);
    alert("test return!") ;
}

输出的结果是:
test return!
this is send!
this is response handler!

而我期望的结果是:
this is send!
this is response handler!
test return!


#7


引用 5 楼 jslang 的回复:
为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

#8


关于JavaScript中实现异步处理、同步等待是否可以?

国外网站上找到的同样的问题,不知道人家怎么实现的!

#9


引用 7 楼 yyfzy 的回复:
Quote: 引用 5 楼 jslang 的回复:

为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

一定要同步的话,只能在websocket对象上着手,看看websocket的api有没有同步/异步的设置。
websocket对象中没有的话。js也无能为力。

其实你不允许用户做其他的操作,可以在页面上用一个与页面100%大的透明层或透明图片把页面盖起来,并屏蔽键盘按键。

#10


引用 9 楼 jslang 的回复:
Quote: 引用 7 楼 yyfzy 的回复:

Quote: 引用 5 楼 jslang 的回复:

为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

一定要同步的话,只能在websocket对象上着手,看看websocket的api有没有同步/异步的设置。
websocket对象中没有的话。js也无能为力。

其实你不允许用户做其他的操作,可以在页面上用一个与页面100%大的透明层或透明图片把页面盖起来,并屏蔽键盘按键。


socket通信肯定是异步的,不可能做到同步。
你的说法是可以阻止用户操作,很多网页上的进度条也是这个目的。

但是我最终的目的是想把“发送命令”和“处理响应”这个过程在JS中封装成一个函数,这样在html中只有像调用普通函数一样就可以得到正确的结果,而不是让Html中提供回调函数或者是事件处理函数。
因为命令有上百个、每个命令的响应数据的参数也不相同,所以想把响应数据的解析封装在JS里,html中不涉及业务逻辑,这样减轻前端人员的开发工作。

#11


肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////

#12


引用 11 楼 showbo 的回复:
肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

#13


引用 12 楼 yyfzy 的回复:
Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise

#14


引用 13 楼 showbo 的回复:
Quote: 引用 12 楼 yyfzy 的回复:

Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise


JS里没有办法主动去查询是否有事件到来?比如C++里可以GetMessage()来查询是否有消息、如果有就处理、没有就继续阻塞。

在Windows下,如果使用C++开发程序,在主线程中等待一个事情的发生时,如果直接用:
bool bContinue = false;
......
while (!bContinue){Sleep(1000)};

这样也会导致主线程无法响应其他改变bContinue状态的事件,导致挂机。但是如果加上消息循环,主线程在等的同时去主动查询是否有消息要处理,就不会出现这个情况。比如:

ULONG WaitFor(bool flag)
{
MSG msg;

while (!flag)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

bool bContinue = false;
..........
WaitFor(bContine);
...........

这样的等待就不会导致挂机,因为当其他线程发送消息(事件)时,主线程能响应、标记bContinue 能被改变!

我现在在JS中就是要实现这么一个等待函数,如果JS中能主动查询事件、并处理,就可以满足我的要求。

谢谢!!!

#15


还有人知道吗?

#16


引用 15 楼 yyfzy 的回复:
还有人知道吗?
不是说了js目前没办法做到,要等es6的普及。。

#17


引用 14 楼 yyfzy 的回复:
Quote: 引用 13 楼 showbo 的回复:

Quote: 引用 12 楼 yyfzy 的回复:

Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise


JS里没有办法主动去查询是否有事件到来?比如C++里可以GetMessage()来查询是否有消息、如果有就处理、没有就继续阻塞。

在Windows下,如果使用C++开发程序,在主线程中等待一个事情的发生时,如果直接用:
bool bContinue = false;
......
while (!bContinue){Sleep(1000)};

这样也会导致主线程无法响应其他改变bContinue状态的事件,导致挂机。但是如果加上消息循环,主线程在等的同时去主动查询是否有消息要处理,就不会出现这个情况。比如:

ULONG WaitFor(bool flag)
{
MSG msg;

while (!flag)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

bool bContinue = false;
..........
WaitFor(bContine);
...........

这样的等待就不会导致挂机,因为当其他线程发送消息(事件)时,主线程能响应、标记bContinue 能被改变!

我现在在JS中就是要实现这么一个等待函数,如果JS中能主动查询事件、并处理,就可以满足我的要求。

谢谢!!!


js目前没有这种功能。。

#18


楼主有找到办法吗?
我也想知道js能不能阻塞等待信号量。

我现在是通过 c++实现js方法 来实现阻塞等待的。

#1


顺便说一句!

一般人们会建议我,在send一个命令之后马上返回、然后等响应时间触发之后再处理(使用回调函数)、也就是说异步执行,让页面步等待。

但是我希望的是用户在一个操作完成之前、不能进行其他操作,所以希望每个JS函数都是同步(阻塞)的。不希望用户发送一个命令之后就不管结果、页面还能接受用户其他操作。

#2


用回调函数
在getServerTime接收一个callback,在onmessage时调用

#3


引用 2 楼 Free_Wind22 的回复:
用回调函数
在getServerTime接收一个callback,在onmessage时调用


即使这样做,函数getServerTime()还是会在send()之后马上返回!
而我的要求是等处理完服务器的响应数据之后、函数getServerTime()才返回。

#4


js没有阻塞功能,ajax同步也会造成浏览器无响应

代码结构要换一下。或者用promise, jscex改写一下

#5


为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。

#6


用promise只能解决“发送消息”和“处理响应”之间的同步关系,但是不能阻止调用函数直接返回。

比如:

       function fnSend(){
           var p = new Promise() ;
           alert("this is send!") ;  
           p.done() ;
           return p ; 
         }
       function fnHandler(){
          var p = new Promise() ;
          alert("this is response handler!") ;
          p.done() ;
          return p ;
       } 

function test() {
    fnSend().then(fnHandler);
    alert("test return!") ;
}

输出的结果是:
test return!
this is send!
this is response handler!

而我期望的结果是:
this is send!
this is response handler!
test return!


#7


引用 5 楼 jslang 的回复:
为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

#8


关于JavaScript中实现异步处理、同步等待是否可以?

国外网站上找到的同样的问题,不知道人家怎么实现的!

#9


引用 7 楼 yyfzy 的回复:
Quote: 引用 5 楼 jslang 的回复:

为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

一定要同步的话,只能在websocket对象上着手,看看websocket的api有没有同步/异步的设置。
websocket对象中没有的话。js也无能为力。

其实你不允许用户做其他的操作,可以在页面上用一个与页面100%大的透明层或透明图片把页面盖起来,并屏蔽键盘按键。

#10


引用 9 楼 jslang 的回复:
Quote: 引用 7 楼 yyfzy 的回复:

Quote: 引用 5 楼 jslang 的回复:

为什么要用阻塞的,长时间阻塞会让浏览器无响应。
你用回调函数不好么。


不好,因为我的js和服务器之间的“发送消息-处理响应”是一个原子操作,中间不允许用户做其他的操作!
当然,我会做超时和异常处理。

一定要同步的话,只能在websocket对象上着手,看看websocket的api有没有同步/异步的设置。
websocket对象中没有的话。js也无能为力。

其实你不允许用户做其他的操作,可以在页面上用一个与页面100%大的透明层或透明图片把页面盖起来,并屏蔽键盘按键。


socket通信肯定是异步的,不可能做到同步。
你的说法是可以阻止用户操作,很多网页上的进度条也是这个目的。

但是我最终的目的是想把“发送命令”和“处理响应”这个过程在JS中封装成一个函数,这样在html中只有像调用普通函数一样就可以得到正确的结果,而不是让Html中提供回调函数或者是事件处理函数。
因为命令有上百个、每个命令的响应数据的参数也不相同,所以想把响应数据的解析封装在JS里,html中不涉及业务逻辑,这样减轻前端人员的开发工作。

#11


肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////

#12


引用 11 楼 showbo 的回复:
肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

#13


引用 12 楼 yyfzy 的回复:
Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise

#14


引用 13 楼 showbo 的回复:
Quote: 引用 12 楼 yyfzy 的回复:

Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise


JS里没有办法主动去查询是否有事件到来?比如C++里可以GetMessage()来查询是否有消息、如果有就处理、没有就继续阻塞。

在Windows下,如果使用C++开发程序,在主线程中等待一个事情的发生时,如果直接用:
bool bContinue = false;
......
while (!bContinue){Sleep(1000)};

这样也会导致主线程无法响应其他改变bContinue状态的事件,导致挂机。但是如果加上消息循环,主线程在等的同时去主动查询是否有消息要处理,就不会出现这个情况。比如:

ULONG WaitFor(bool flag)
{
MSG msg;

while (!flag)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

bool bContinue = false;
..........
WaitFor(bContine);
...........

这样的等待就不会导致挂机,因为当其他线程发送消息(事件)时,主线程能响应、标记bContinue 能被改变!

我现在在JS中就是要实现这么一个等待函数,如果JS中能主动查询事件、并处理,就可以满足我的要求。

谢谢!!!

#15


还有人知道吗?

#16


引用 15 楼 yyfzy 的回复:
还有人知道吗?
不是说了js目前没办法做到,要等es6的普及。。

#17


引用 14 楼 yyfzy 的回复:
Quote: 引用 13 楼 showbo 的回复:

Quote: 引用 12 楼 yyfzy 的回复:

Quote: 引用 11 楼 showbo 的回复:

肯定是居于回调了,做个函数,指令和回调存储起来,onmessage中服务器端同时返回指令和名称,然后通过返回的指令获取回调执行


  
  var _socket;

    function init() {
        // 创建一个Socket实例,尝试连接服务器
        _websocket = new WebSocket('ws://127.0.0.1:' + _serverPort);

        // 握手成功
        _websocket.onopen = function (e) {
            _isConnected = true;
        };

        // 监听消息
        _websocket.onmessage = function (event) {
            _isResponded = true;
            _respData = event.data;
////////////////////////////////////////////////////////////////
            var data = JSON.parse(_respData);//服务器端返回类似{"cmd":"发送的指令名称","data":"数据,也可以为json格式字符串"}的json字符串,然后JSON.parse转为json对象
            MessageList[data.cmd](data.data);//执行回调
////////////////////////////////////////////////////////////////
        };

        // 监听Socket的关闭
        _websocket.onclose = function (event) {
            socket = null;
            alert("连接关闭!");
        };
    }
////////////////////////////////////////////////////////////////
    var MessageList = {};
    function SendMsg(cmd, callback) {
        MessageList[cmd] = callback;
        _websocket.send(cmd);
    }
    SendMsg("{get_time}", function (data) {
        console.log(data)
    })
////////////////////////////////////////////////////////////////


回调我知道,我的问题不是“怎么处理响应数据”;而是“在处理完响应数据之前如何阻塞JS进程、一直等待而又能响应onmessage事件”。

目前来说无解,单线程的,只能居于回调。除非你等待浏览器厂商全部实现es6标准,就可以用promise对象
http://es6.ruanyifeng.com/#docs/promise


JS里没有办法主动去查询是否有事件到来?比如C++里可以GetMessage()来查询是否有消息、如果有就处理、没有就继续阻塞。

在Windows下,如果使用C++开发程序,在主线程中等待一个事情的发生时,如果直接用:
bool bContinue = false;
......
while (!bContinue){Sleep(1000)};

这样也会导致主线程无法响应其他改变bContinue状态的事件,导致挂机。但是如果加上消息循环,主线程在等的同时去主动查询是否有消息要处理,就不会出现这个情况。比如:

ULONG WaitFor(bool flag)
{
MSG msg;

while (!flag)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

bool bContinue = false;
..........
WaitFor(bContine);
...........

这样的等待就不会导致挂机,因为当其他线程发送消息(事件)时,主线程能响应、标记bContinue 能被改变!

我现在在JS中就是要实现这么一个等待函数,如果JS中能主动查询事件、并处理,就可以满足我的要求。

谢谢!!!


js目前没有这种功能。。

#18


楼主有找到办法吗?
我也想知道js能不能阻塞等待信号量。

我现在是通过 c++实现js方法 来实现阻塞等待的。