Я пытаюсь передавать сообщения между скриптом контента и расширением

Вот что я имею в скрипте контента

chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
  console.log(response)
});

И в backgro und script У меня есть

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.type == "getUrls"){
      getUrls(request, sender, sendResponse)
    }
});

function getUrls(request, sender, sendResponse){
  var resp = sendResponse;
  $.ajax({
    url: "http://localhost:3000/urls",
    method: 'GET',
    success: function(d){
      resp({urls: d})
    }
  });

}

Теперь, если я отправлю ответ до вызова ajax в getUrls функция, ответ отправляется успешно, но в методе успеха вызова ajax, когда я отправляю ответ, он не отправляет его, когда я перехожу к отладке, я вижу, что порт является нулевым внутри кода для { *} From sendResponse.

Просто поместите это в заголовок вашей PHP-страницы, и она будет работать без API: jsFiddle Array.prototype.smartSort (‘asc | desc’) chrome.runtime.onMessage.addListener:

метод в библиотеках.

Я удалил вариант return true; напрямую. getUrls чтобы указать, что вы будете вызывать функцию ответа асинхронно.

Принятый ответ правильный, я просто хотел добавить пример кода, который упрощает это Проблема в том, что API (на мой взгляд) не очень хорошо разработан, потому что заставляет нас, разработчиков, знать, будет ли конкретное сообщение обрабатываться асинхронно или нет. Если вы обрабатываете много разных сообщений, это становится невыполнимой задачей, потому что вы никогда не знаете, если глубоко внутри какой-либо функции переданный sendResponse будет называться async или нет. Обдумайте это:

chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
if (request.method == "method1") {
    handleMethod1(sendResponse);
}

Как я могу узнать, что глубоко внутри handleMethod1. handleMethod1 знает, что это сломает абонента, введя что-то асинхронное?

Мое решение таково:

chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {

var responseStatus = { bCalled: false };

function sendResponse(obj) {  //dummy wrapper to deal with exceptions and detect async
    try {
        sendResponseParam(obj);
    } catch (e) {
        //error handling
    }
    responseStatus.bCalled= true;
}

if (request.method == "method1") {
    handleMethod1(sendResponse);
}
else if (request.method == "method2") {
    handleMethod2(sendResponse);
}
...

if (!responseStatus.bCalled) { //if its set, the call wasn't async, else it is.
    return true;
}

});

По сравнению с решением Lavamantis мы можем сделать …

Если вы используете библиотеку lodash, вы можете использовать метод округления lodash, как показано ниже. правильно, я только что добавил некоторые функции: Это может помочь вам:

. Тем не менее, не беспокойтесь об этой проблеме слишком много. Это станет проблемой только для объектов с длительным сроком службы, к которым постоянно добавляются новые ключи. В любом другом случае (который есть почти в каждом случае в программировании реального мира) наиболее целесообразно использовать

Browser.runtime.onMessage.addListener( request => new Promise( resolve => {
    if( !request || typeof request !== 'object' || request.type !== "getUrls" ) return;

    $.ajax({
        'url': "http://localhost:3000/urls",
        'method': 'GET'
    }).then( urls => { resolve({ urls }); });
}) );