英文:
How to use async properly to get chrome.storage?
问题
I've translated the code portions for you:
background.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.type === "request") {
var scoresVar = findScores(request.table, "All");
console.log("Sending response " + scoresVar);
sendResponse({scores: scoresVar})
}
else if (request.type === "score") {
saveScore(request.website, request.score, request.tab);
sendResponse("Finished adding score " + request.score);
}
}
);
function findScores(table, website) {
const categories = table.split("-");
if (categories.includes("personal")) {
chrome.storage.sync.get([website], function(response) {
if (!(typeof response[website] === 'undefined')) {
console.log("Found " + response[website]);
return response[website];
}
});
} else if (categories.includes("global")){
// TODO: Add global leaderboards
return ["-"];
}
console.log("Didn't find, on default");
return ["-"];
}
popup.js
async function requestScores(tableID) {
var url = "All"
if (tableID.includes("current")) {
var url = await getCurrentTab();
}
console.log("Sending message to load scores to " + url);
(async () => {
const response = await chrome.runtime.sendMessage({type: "request", request: "load scores", table: tableID, tab: url});
console.log("Received: " + response);
// add scores to HTML DOM
});
})();
}
Please note that I've kept the code structure as-is while translating it to Chinese. If you have any specific questions or need further assistance, feel free to ask.
英文:
I am creating a google chrome extension. On the popup, I am displaying a leaderboard. However, I am new to JavaScript so I don't know how to properly use async. I am using chrome.storage to get stored scores to display on the leaderboard, then sending them from background.js to score.js. My issue is that, since chrome.storage.get happens asynchronously, my findScores method does not wait for chrome.storage.get to finish before incorrectly returning a default empty score.
Here is my code:
background.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.type === "request") {
var scoresVar = findScores(request.table, "All");
console.log("Sending response " + scoresVar);
sendResponse({scores: scoresVar})
}
else if (request.type === "score") {
saveScore(request.website, request.score, request.tab);
sendResponse("Finished adding score " + request.score);
}
}
);
function findScores(table, website) {
const categories = table.split("-");
if (categories.includes("personal")) {
chrome.storage.sync.get([website], function(response) {
if (!(typeof response[website] === 'undefined')) {
console.log("Found " + response[website]);
return response[website];
}
});
} else if (categories.includes("global")){
// TODO: Add global leaderboards
return ["-"];
}
console.log("Didn't find, on default");
return ["-"];
}
popup.js
async function requestScores(tableID) {
var url = "All"
if (tableID.includes("current")) {
var url = await getCurrentTab();
}
console.log("Sending message to load scores to " + url);
(async () => {
const response = await chrome.runtime.sendMessage({type: "request", request: "load scores", table: tableID, tab: url});
console.log("Received: " + response);
// add scores to HTML DOM
});
})();
}
My console messages reveal that I first return a default score, which is sent to popup.js. I have tried throwing async keywords in front of functions (as well as "await" in front of variables like scoresVar = await findScores(request.table, "All") but it just caused more issues, where findScores still returned a default value, but background.j instead sent an undefined promise.
How can I fix my code?
答案1
得分: 0
使用Promise
和async
/await
而不是回调函数更简单。如果不传递回调函数,chrome.storage.sync.get
将返回一个Promise
。
async function findScores(table, website) {
// ...
if (categories.includes("personal")) {
const response = await chrome.storage.sync.get([website]);
if (response[website] !== undefined) {
console.log("Found " + response[website]);
return response[website];
}
}
// ...
}
// ...
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// ...
findScores(request.table, "All").then(scores => {
console.log("Sending response " + scores);
sendResponse({scores});
});
return true; // 保持消息通道打开,以便sendResponse可以异步工作
});
请注意,onMessage的回调函数应返回一个字面值true
值(文档),以保持内部消息通道打开,以便sendResponse可以异步工作。
英文:
It is simpler to work with Promise
s and async
/await
instead of callbacks. chrome.storage.sync.get
returns a Promise
if you do not pass a callback.
async function findScores(table, website) {
// ...
if (categories.includes("personal")) {
const response = await chrome.storage.sync.get([website]);
if (response[website] !== undefined) {
console.log("Found " + response[website]);
return response[website];
}
}
// ...
}
// ...
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// ...
findScores(request.table, "All").then(scores => {
console.log("Sending response " + scores);
sendResponse({scores});
});
return true; // keep the messaging channel open for sendResponse
});
Note that the callback of onMessage should return a literal true
value (documentation) in order to keep the internal messaging channel open so that sendResponse can work asynchronously.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论