3

Je construis ma première extension de chrome, qui crée une liste de lecture de liens en saisissant des URL à partir d'une page Web. Cependant, je suis accroché à ma fonction de messagerie. J'ai écrit une fonction de test appelée 'test' dans mon objet playlist, et j'essaye simplement d'assigner le message que le script de contenu renvoie (via la fonction getPageInfo) à une variable de ma fonction objet. Cependant, même si je reçois un message, la chaîne se perd entre l'instruction return et la fonction de test. Voici mon script de fond:La fonction d'extension de Chrome renvoie la chaîne comme non définie

//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 
}); 

Et voici mon script de contenu:

//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 
}); 

Et voici mon manifeste:

{ 
"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 
} 
} 

J'ai la retourner pendant quelques jours, mais je ne peux pas comprendre ce que je fais mal. Des idées? Merci!

+0

Il est pas "se perdre". Tout chrome. * L'API est asynchrone. Vous pourriez vouloir lire quelque chose sur le code asynchrone dans js. Copie possible: [Comment renvoyer la réponse d'un appel asynchrone?] (Http://stackoverflow.com/q/14220321) – wOxxOm

Répondre

0

Vous ne pouvez pas transformer une fonction asynchrone en synchrone. Vous devez ajouter le paramètre callback pour getPageInfo et l'utiliser pour renvoyer la valeur.

Quelque chose comme ceci:

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); 
     }); 
    }); 
} 

Ou encore mieux serait d'utiliser des promesses:

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); 
})