等待事件再返回

时间:2018-10-16 07:07:17

标签: javascript asynchronous

我有一个用JavaScript编写的函数,无法修改:

function doSomething() {
    doFirst();
    (...)
}

doSomething内部的第一个函数通过WebSocket发送一个数据包,并且必须等待响应才能返回。因此,换句话说,我需要doFirst在执行(...)之前等待此响应。

首先想到的是,我认为可以在doFirst完成后使用回调函数来调用(...),但是我不能这样做,因为我无法在doSomething上写任何东西,因此以下示例完全不可能:

function doSomething() {
    doFirst(function() {
        (...)
    });
}

因此,在这种限制下,我必须能够在doFirst内编写一些内容(但要再次声明,不是doSomething)以实现此行为。

如果我只声明WebSocket的onmessage回调,则(...)在套接字获得响应之前完成,并且如果我使用类似以下内容的话:

while(!received) { } 

当然,浏览器会挂起,即使我得到响应,也无法继续。

4 个答案:

答案 0 :(得分:1)

轮询,就像您的while(!received)一样,但是有一个睡眠,因此eventloop允许之间有其他指令。即:

const checkInterval = setInterval(function(){
  if(!received) return;
  clearInterval(checkInterval);
  //do your stuff here
}, 10)

答案 1 :(得分:0)

我认为使用flag的传统解决方案会很有用。您可以在flag=FalsedoSomething()之外初始化变量doFirst(),并在得到响应时将其设为flag=True

答案 2 :(得分:0)

还有另一种“可能的”方法,这是一种基于Promise的方法,该方法仍然依赖于间隔,但是隔离了其余的代码。

var _onceReceived = function(timeoutSeverity) {
    return new Promise(function(resolve, reject){
    var _mInterval = setInterval(function(){
      if (received !== null && received !== undefined) {
        clearInterval(_mInterval);
        resolve(received);
      }
    }, timeoutSeverity);
  });
}

基本上,这将查找收到的变量并检查其是否有效,从而使您可以根据所需的严重性设置自定义超时。

样品用量:

_onceReceived(1000).then(function(res){
    alert('received was now set, and it is: ' + res);
});

完整样本:

var received;
function doesSomething() {
    setTimeout(function(){
        received = 10;      
  }, 5000);
}

var _onceReceived = function(timeoutSeverity) {
    return new Promise(function(resolve, reject){
    var _mInterval = setInterval(function(){
        console.log('checking!');
      if (received !== null && received !== undefined) {
        clearInterval(_mInterval);
        resolve(received);
      }
    }, timeoutSeverity);
  });
}

doesSomething();
_onceReceived(1000).then(function(res){
    alert('received was now set, and it is: ' + res);
});

有效的提琴:http://jsfiddle.net/m1zs5vcw/1/

答案 3 :(得分:0)

您可以通过基于承诺和等待操作员的操作来完成此操作。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

function doFirst() {
    return new Promise(resolve => {
        setTimeout(() => {
          resolve('do first');
        }, 2000);
      });
    }

    async function doSomething() {
     var received =  await doFirst();
       console.log(received);
    }