3

Я создаю свое первое расширение chrome, которое создает список воспроизведения ссылок, захватывая URL-адреса с веб-страницы. Тем не менее, я повесил трубку на функцию обмена сообщениями. Я написал тестовую функцию под названием «test» внутри моего объекта списка воспроизведения, и я просто пытаюсь назначить сообщение, которое сценарий содержимого отправляет обратно (через функцию getPageInfo) в переменную в моей объектной функции. Однако, хотя я возвращаю сообщение, строка теряется между оператором return и тестовой функцией. Вот мой фон сценарий:Функция расширения Chrome Возвращаемая строка как неопределенная

//BACKGROUND.JS 

var Playlist = { 
index: 0, 
playlist: [], 
test: function(info) { 
    var message = "Get Song"; 
    var song = getPageInfo(message); 
    alert(song); //Shows undefined 
    } 
}; 

function getPageInfo(message) { 
var s; 
chrome.tabs.query({active:true, currentWindow:true}, function(tabs) { 
     chrome.tabs.sendMessage(tabs[0].id, {greeting: message}, function(response){ 
      console.log(response.farewell); 
      s = response.farewell; 
      alert(s); //Shows "We did it" 
     }); 
    }); 
alert(s) //Shows "We did it" 
return s; 
} 

chrome.contextMenus.create({ 
title: "Add to Playlist", 
contexts: ["image", "link", "selection"], 
onclick: Playlist.test 
}); 

И вот мое содержание сценария:

//CONTENT.JS 

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) { 
    console.log(sender.tab ? 
     "from a content script:" + sender.tab.url : 
     "from the extension"); 
    if(request.greeting == "Get Song") 
     sendResponse({farewell: "We did it"}); //My message 
}); 

И вот мой манифест:

{ 
"manifest_version": 2, 

"name": "RedditDJ", 
"description": "This app hides jobs which the user has already clicked on.", 
"version": "1.0", 
"content_scripts": [ 
    { 
     "matches": ["http://www.reddit.com/*","https://www.reddit.com/*"], 
     "js": ["script/jquery-2.1.4.js", "script/content.js"] 
    } 
], 
"permissions": [ 
    "http://www.reddit.com/", 
    "https://www.reddit.com/", 
    "http://www.youtube.com/", 
    "https://www.youtube.com/", 
    "http://www.soundcloud.com/", 
    "https://www.soundcloud.com/", 
    "http://*/", 
    "https://*/", 
    "tabs", 
    "contextMenus", 
    "storage" 
], 
"browser_action": { 
    "default_icon": { 
     "19":"style/img/icon_19.png", 
     "38":"style/img/icon_38.png", 
     "128":"style/img/icon_128.png" 
    }, 
    "default_title": "Reddit DJ", 
    "default_popup": "popup.html" 
}, 
"background": { 
    "scripts": ["script/background.js"], 
    "persistent": true 
} 
} 

Я переворачивая его в течение нескольких дней, но я не могу понять, что я делаю неправильно. Есть идеи? Благодаря!

+0

Это не "заблудиться". Все хром. * API является асинхронным. Возможно, вы захотите прочитать что-то в асинхронном коде в js. Возможный дубликат: [Как вернуть ответ от асинхронного вызова?] (Http://stackoverflow.com/q/14220321) – wOxxOm

ответ

0

Вы просто не можете преобразовать асинхронную функцию в синхронную. Вы должны добавить параметр callback для getPageInfo и использовать его для возвращаемого значения.

Что-то вроде этого:

function getPageInfo(message, callback) { 
    chrome.tabs.query({active:true, currentWindow:true}, function(tabs) { 
     chrome.tabs.sendMessage(tabs[0].id, {greeting: message}, function(response) { 
      console.log(response.farewell); 
      s = response.farewell; 
      callback(s); 
     }); 
    }); 
} 

Или еще лучше будет использовать обещание:

function getPageInfo(message) { 
    return new Promise(function(resolve, reject) { 
     chrome.tabs.query({active:true, currentWindow:true}, function(tabs) { 
      chrome.tabs.sendMessage(tabs[0].id, {greeting: message}, function(response) { 
       console.log(response.farewell); 
       s = response.farewell; 
       resolve(s); 
      }); 
     }); 
    }); 
} 


getPageInfo().then(function(value) { 
    alert(value); 
}) 
Смежные вопросы