Chrome扩展功能返回字符串为未定义

3
我正在构建我的第一个Chrome扩展程序,它通过从网页中抓取URL来创建链接播放列表。然而,我在我的消息功能上遇到了问题。我已经在我的播放列表对象中编写了一个名为“test”的测试函数,并尝试将内容脚本通过getPageInfo函数返回的消息分配给对象函数中的变量。但是,虽然我收到了一条消息,但该字符串在返回语句和测试函数之间丢失了。这是我的后台脚本:
//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
}
}

我已经思考了几天,但是我无法弄清楚我做错了什么。 有什么想法吗?谢谢!


这不是“迷失了”。所有的chrome.* API都是异步的。你可能想在js中阅读一些关于异步代码的内容。可能重复:如何从异步调用中返回响应? - wOxxOm
1个回答

0

你不能仅仅将异步函数转换为同步函数。你需要为 getPageInfo 添加 callback 参数,并使用它来返回值。

像这样:

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

甚至更好的方法是使用 Promise:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接