google-chrome-extension Message Passing Send a response asynchronously


Example

In attempt to send a response asynchronously from chrome.runtime.onMessage callback we might try this wrong code:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    $.ajax({
        url: 'https://www.google.com',
        method: 'GET',
        success: function(data) {
            // data won't be sent
            sendResponse(data);
        },
    });
});

However, we would find that data is never sent. This happens because we have put sendResponse inside an asynchronous ajax call, when the success method is executed, the message channel has been closed.

The solution would be simple, as long as we explicitly return true; at the end of the callback, which indicates we wish to send a response asynchronously, so the message channel will be kept open to the other end (caller) until sendResponse is executed.

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    $.ajax({
        url: 'https://www.google.com',
        method: 'GET',
        success: function(data) {
            // data would be sent successfully
            sendResponse(data);
        },
    });

    return true; // keeps the message channel open until `sendResponse` is executed
});

Of course, it applies to an explicit return from the onMessage callback as well:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.action == 'get') {
        $.ajax({
            url: 'https://www.google.com',
            method: 'GET',
            success: function(data) {
                // data would be sent successfully
                sendResponse(data);
            },
        });

        return true; // keeps the message channel open until `sendResponse` is executed
    }

    // do something synchronous, use sendResponse

    // normal exit closes the message channel
});