У меня есть скрипт, который должен получить значение из фонового изображения, в основном он возвращает элемент, но также по какой-то причине он возвращает true при повторном вызове функции.
В элементе фонового сценария всегда объект или неопределенное значение. Как это сбылось в ответ, для меня загадка
market.js
async function renderMarketItem(item) {
//parsers name, type and quality of item
let market_item = await new Promise((resolve, reject) => {
if (chrome.runtime?.id) {
chrome.runtime.sendMessage({
action: "getMarketItem",
name: formatData(type, name, quality)
}, (item) => {
resolve(item);
})
} else resolve(undefined);
});
//another logic
}
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action == 'updateConfig') {
$('.items-grid').children().each(function() {
renderMarketItem($(this));
})
}
});
/*for example*/
$('.items-grid').children().each(function() {
renderMarketItem($(this));
})
фон.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action == 'getMarketItem') {
sendResponse(getMarketItem(message));
}
if (message.action == 'updateConfig') {
updateConfig(message, sender, sendResponse);
}
});
const updateConfig = (message, sender, sendResponse) => {
const {data} = message;
getTabs((tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, { action: 'updateConfig', data });
});
});
}
let getTabs = (callback = ()=>{}) => {
chrome.tabs.query({ url: /*siteUrl*/ }, (tabs) => {
callback(tabs);
});
}
const getMarketItem = (message) => {
let targetName = message.name;
let item;
if (targetName) item = items.find(item => item.market_hash_name.trim() == targetName.trim());
return item;
}
Я выполнил асинхронную функцию с возвратом true, и это не сработало.
В Манифесте V3 chrome.runtime.sendMessage()
возвращает обещание, поэтому вам не нужно использовать new Promise()
и аргумент обратного вызова. Но вы никогда не ждете вызова renderMarketItem()
, так почему же вы вообще возвращаете обещание?
Для примера я сократил код и оставил главное, внизу под market_item
я написал, что там другая логика
Допустим, у меня есть 800 элементов, которые нужно обработать и мне нужно, чтобы они делали это параллельно, т.е. не дожидаясь друг друга.
значение, которое получает обратный вызов, является объектом ответа, отправленным обработчиком сообщения. Ваш onMessage
слушатель не справляется action: "getMarketItem"
, какой реакции вы ожидаете?
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action == 'getMarketItem') { sendResponse(getMarketItem(message)); } });
в background.js
Упс, пропустил это во втором блоке кода.
Если вызвать renderMarketItem не в chrome.runtime.onMessage.addListener, все работает нормально, проблема именно с работой в обработчике
1) true
вероятно из старой версии кода. Перезагрузите расширение в chrome://extensions и перезагрузите вкладку. 2) Ваш прослушиватель setTimeout не связан с основным кодом, поскольку он получает данные от chrome.tabs.sendMessage, который вы не показали.
1)Я всегда перезагружаю расширение после изменения кода 2) setTimeout - это просто костыль, который иногда не работает, поэтому не надо на него обращать внимание
Проблема была в моем всплывающем приложении React.
useEffect(() => {
const handleMessage = async (message: any, sender: any, sendResponse: () => void) => {
if (message.action === 'getConfig' && message.data) setConfig(message.data);
return true;
};
runtime.onMessage.addListener(handleMessage);
runtime.sendMessage({ action: 'needConfig' });
return () => {
runtime.onMessage.removeListener(handleMessage);
};
}, []);
Этот прослушиватель прервал прослушиватель сценария содержимого, и когда всплывающее окно было открыто, оно вернуло значение true.
Я удалил прослушиватель и использовал шаблон одноразового запроса, где ответ возвращается sendMessage:
useEffect(() => {
const getConfig = async() => {
let cfg = await runtime.sendMessage({ action: 'getConfig'});
console.info(cfg);
setConfig(cfg);
}
getConfig();
}, []);
В чем смысл переменной
market_item
? Вы никогда не используете его.