Функция обратного вызова chrome.tabs.sendMessage не вызывается. Почему?

У меня есть следующий метод, который вызывается из фонового скрипта моего расширения Chrome. Цель состоит в том, чтобы отправить сообщение на определенную вкладку, а затем вызвать предоставленный метод обратного вызова с результатом. Важно то, что callbackDone должен всегда вызываться в какой-то момент времени. Итак, это происходит так:

function sendToTab(nTabID, callbackDone)
{
    (function()
    {
        chrome.tabs.sendMessage(nTabID, {
            action: "update01"
        }, 
        function(response) 
        {
            if(chrome.runtime.lastError)
            {
                //Failed to send message to the page
                if(callbackDone)
                    callbackDone(nTabID, null); //Page never received the message
            }
            else
            {
                //Sent message OK
                if(response.result === true)
                {
                    if(callbackDone)
                        callbackDone(nTabID, true); //Success!
                }
                else
                {
                    if(callbackDone)
                        callbackDone(nTabID, false);    //Page returns failure
                }
            }
        });
    }());
}

Затем изнутри страницы, которая обрабатывает сообщение (может быть внедренным content script), я обрабатываю его как таковое:

chrome.runtime.onMessage.addListener(onMessageProc);

function onMessageProc(request, sender, sendResponse)
{
    if(request.action == "update01")
    {
        //Do processing .... that sets `bResult`

        sendResponse({result: bResult});
    }
}

Приведенный выше подход работает достаточно хорошо, за исключением... Скажем, есть страница, например Сценарий страницы параметров, которая не обрабатывает мое update01 сообщение, а вместо этого обрабатывает свое собственное сообщение как таковое:

chrome.runtime.onMessage.addListener(onMessageProc);

function onMessageProc(request, sender, sendResponse)
{
    if(request.action == "update02")   //Note different action ID
    {
        //Does some other actions...
    }
}

В этом случае, когда мой первый метод sendToTab вызывается для этой вкладки, мой callbackDone никогда не вызывается, т. е. chrome.tabs.sendMessage вызывается и немедленно возвращается, но его функция обратного вызова никогда не вызывается.

Итак, что мне здесь не хватает?


person c00000fd    schedule 22.09.2014    source источник
comment
Я не думаю, что это весь соответствующий код.   -  person Xan    schedule 22.09.2014
comment
@Xan: О чем ты говоришь?   -  person c00000fd    schedule 22.09.2014
comment
Я думал, что важно, что в ваших слушателях. Это так, но вашего фрагмента кода достаточно.   -  person Xan    schedule 22.09.2014


Ответы (1)


Вы видите ожидаемое поведение.

В документации говорится о функции обратного вызова:

Если вы укажете параметр responseCallback, это должна быть функция, которая выглядит так:

function(any response) {...};

any response
Объект ответа JSON, отправленный обработчиком сообщения. Если при подключении к указанной вкладке произойдет ошибка, обратный вызов будет вызван без аргументов, а runtime.lastError будет установлено в сообщение об ошибке.

Есть 3 возможных результата выполнения sendMessage.

  1. Был прослушиватель, и он вызвал sendResponse.
    Затем вызывается обратный вызов с ответом в качестве параметра.

  2. Был прослушиватель, и он завершился без вызова sendResponse (синхронно или асинхронно).
    Затем обратный вызов вообще не вызывается.

  3. Произошла какая-то ошибка при отправке сообщения.
    Затем вызывается обратный вызов без аргументов и устанавливается chrome.runtime.lastError.

Если вам нужно, чтобы ваш обратный вызов выполнялся при любых обстоятельствах, вам понадобится случай по умолчанию в ваших слушателях, который вызывает sendResponse.

person Xan    schedule 22.09.2014
comment
Спасибо. Хотя было бы очень полезно, если бы ваши 3 пункта были включены в документацию. Или, по крайней мере, устранит баги и путаницу... Откуда вы все это знаете? - person c00000fd; 22.09.2014
comment
В данном случае я только что проверил это. Затем перекрестные ссылки с документацией, и приведенную выше цитату можно интерпретировать так. - person Xan; 22.09.2014
comment
@ c00000fd Вы не вызываете свой sendResponse и задаетесь вопросом, почему функция response никогда не вызывается? Похоже на ожидаемое поведение для меня. - person Teepeemm; 22.09.2014
comment
@ Типимм, я не знаю. Я ожидаю, что обратный вызов будет вызываться без аргументов и с неустановленным chrome.runtime.lastError. Я полагаю, что c00000fd тоже. - person Xan; 22.09.2014