如何在Javascript中使回调函数同步?

时间:2015-07-15 06:20:30

标签: javascript asynchronous google-chrome-extension

通过“synchronized”我的意思是,在函数内部阻塞。这个函数不能返回,直到我预期发生的事情,这个东西打破了块。

var val; // val will be assigned at some unexpected time

// the function is like below
chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
{
     /* Here is the block, waiting for smth to happen (e.g. val being assigned) */

    sendResponse(val); // val will be sent back after val was assigned
}

1 个答案:

答案 0 :(得分:2)

。因为你不能做互斥式的同步。

JavaScript是单线程的。想象一下以下代码:

chrome.runtime.onMessage.addListener(function(request,sender,sendResponse){
    while(typeof val == undefined) {}
    sendResponse(val);//val will be send back after val assigned
});

似乎就像循环一样,直到分配发生;但是,在实践中,如果它进入循环,它将保证永远循环。 JS使用队列处理事物,您只需确保当前任务永远不会结束。

所以你需要以这种或那种方式放弃控制。

  1. 回复你还没有答案!

    chrome.runtime.onMessage.addListener(function(request,sender,sendResponse) {      
        if(typeof val == undefined) {
          sendResponse(); // check for undefined on the other side
        } else {
          sendResponse(val);
        }
    });
    

    然后调整接收端的逻辑。

    但这可能不是一个好的解决方案。在那种情况下......

  2. 通过对请求进行排队来延迟响应。 Chrome允许您异步使用sendResponse,但您必须指出:

      

    当事件侦听器返回时,此函数 [sendResponse] 无效,除非您从事件侦听器返回true,表示您希望发送响应异步(这将使消息通道保持打开到另一端,直到调用sendResponse。)

    所以这可能是这样的:

    var requests = [];
    
    chrome.runtime.onMessage.addListener(function(request,sender,sendResponse) {
        if(typeof val == undefined) {
          requests.push(sendResponse);
          return true;
        } else {
          sendResponse(val);
        }
    });
    
    /* ... */
    
    val = theActualValue;
    for(callback of requests) callback(val);
    requests = [];