Данные обратного вызова из sendMessage верны

У меня есть скрипт, который должен получить значение из фонового изображения, в основном он возвращает элемент, но также по какой-то причине он возвращает 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, и это не сработало.

В чем смысл переменной market_item? Вы никогда не используете его.

Barmar 10.05.2024 18:23

В Манифесте V3 chrome.runtime.sendMessage() возвращает обещание, поэтому вам не нужно использовать new Promise() и аргумент обратного вызова. Но вы никогда не ждете вызова renderMarketItem(), так почему же вы вообще возвращаете обещание?

Barmar 10.05.2024 18:27

Для примера я сократил код и оставил главное, внизу под market_item я написал, что там другая логика

THEMOD 10.05.2024 18:38

Допустим, у меня есть 800 элементов, которые нужно обработать и мне нужно, чтобы они делали это параллельно, т.е. не дожидаясь друг друга.

THEMOD 10.05.2024 18:40

значение, которое получает обратный вызов, является объектом ответа, отправленным обработчиком сообщения. Ваш onMessage слушатель не справляется action: "getMarketItem", какой реакции вы ожидаете?

Barmar 10.05.2024 18:44
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action == 'getMarketItem') { sendResponse(getMarketItem(message)); } }); в background.js
THEMOD 10.05.2024 18:45

Упс, пропустил это во втором блоке кода.

Barmar 10.05.2024 18:46

Если вызвать renderMarketItem не в chrome.runtime.onMessage.addListener, все работает нормально, проблема именно с работой в обработчике

THEMOD 10.05.2024 18:48

1) true вероятно из старой версии кода. Перезагрузите расширение в chrome://extensions и перезагрузите вкладку. 2) Ваш прослушиватель setTimeout не связан с основным кодом, поскольку он получает данные от chrome.tabs.sendMessage, который вы не показали.

woxxom 10.05.2024 19:54

1)Я всегда перезагружаю расширение после изменения кода 2) setTimeout - это просто костыль, который иногда не работает, поэтому не надо на него обращать внимание

THEMOD 10.05.2024 20:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
10
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема была в моем всплывающем приложении 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();
  }, []);

Другие вопросы по теме