-1

By "synchronized" I mean, blocks inside a function. This function cannot return until something I expected happens, and this thing breaks the block.

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
}
SevenWow
  • 305
  • 3
  • 14
  • @uselesschien, It seems cannot do. Here is my another post(http://stackoverflow.com/questions/31201420/chrome-extension-native-messaging-synchronization?). – SevenWow Jul 15 '15 at 06:24
  • 1
    You can't really do blocking inside JavaScript. You must use either callback functions or promises. –  Jul 15 '15 at 06:25
  • Embrace asynchronicity! In Javascript some things are done asynchronously so, really, it will make your life so much easier if you just go with it. Chrome [has support for promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Browser_compatibility), which is a good way of thinking about asynchronous events. – Sverri M. Olsen Jul 15 '15 at 06:27
  • @AwalGarg this somethig is an event handler, it fires when my hostapp send data to chrome. – SevenWow Jul 15 '15 at 06:31
  • @SverriM.Olsen yes async is the future, but here, do you notice my function itself is an event handler and it cannot return before another event handler fires and sets a value, so my function can return the value. – SevenWow Jul 15 '15 at 06:35

1 Answers1

2

You don't. Because you can't do mutex-style synchronization.

JavaScript is single-threaded. Imagine the following code:

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

It seems like it will loop until the assignment happens; however, in practice it is guaranteed to loop forever if it enters the loop. JS processes things with a queue, and you just made sure the current task never ends.

So you will need to relinquish control one way or another.

  1. Just reply that you don't have an answer yet!

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

    Then adjust the logic on the receiving end.

    But that might not be a good solution. In that case..

  2. Delay the response, by queuing the requests. Chrome allows you to use sendResponse asynchronously, but you have to indicate that:

    This function [sendResponse] becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

    So this might be something like this:

    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 = [];
    
Xan
  • 74,770
  • 16
  • 179
  • 206
  • P.S. `for..of` I used above is a nifty new JS construct supported by Chrome; you can read about it [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of). – Xan Jul 15 '15 at 07:31
  • Thanks a lot for your reply, it helps me understand 'js' much better. About my question here, I found another way of communication between Chrome extension backpage and local host app. If you're interested, you can have a look here(http://stackoverflow.com/questions/31201420/chrome-extension-native-messaging-synchronization). :-) – SevenWow Jul 16 '15 at 05:07