如何正确使用异步来获取chrome.storage?

huangapple go评论54阅读模式
英文:

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

使用Promiseasync/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 Promises 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.

huangapple
  • 本文由 发表于 2023年6月1日 11:04:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76378419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定