Chrome.runtime.onMessage.addListener() запускается несколько раз

Функция chrome.runtime.onMessage.addListener() вызывается один раз для первого полученного сообщения, но впоследствии она вызывается несколько раз, причем число вызовов увеличивается с каждым последующим сообщением. Пример проблемы приведен на этом изображении: нажмите здесь, чтобы просмотреть изображение

Расширение нацелено на определенную вкладку Chrome, на которой воспроизводится локальный видеофайл, а действия предназначены исключительно для этой вкладки.

Код, вызывающий проблему:

контент.js

// content.js
console.info("--- Start of Content.js --");

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {

    console.info("Entered onMessage.addListener")
    var video = document.querySelector("video");
    
    if (!video) return;

    switch (request.action) {
        case "play":
            video.play();
            break;
        case "pause":
            video.pause();
            break;
        case "forward":
            video.currentTime += 5;
            break;
        case "backward":
            video.currentTime -= 5;
            break;
    }
});

фон.js

// background.js
console.info("Background.js");

const urlTest = 'https://api-endpoint.com/get';

function checkAndDoAction() {
    fetch(urlTest)
        .then(response => response.text())
        .then(data => {
            if (data !== "None") {

                const action_ = data.trim();
                
                queryInfo = {'url': 'file:///Users/username/*'};

                chrome.tabs.query(queryInfo, function(tabs) {
                    chrome.scripting.executeScript({
                        target: { tabId: tabs[0].id },
                        files: ["content.js"]
                    }).then(() => {
                        console.info("sending msg to content" )
                        chrome.tabs.sendMessage(tabs[0].id, { action: action_ });
                    }).catch((error) => {
                        console.error("Error executing script:", error);
                    });
                });

            }
        })
        .catch(error => console.error("Error:", error));
}

setInterval(checkAndDoAction, 500);

манифест.json

{
    "manifest_version": 3,
    "name": "Video Controller - extension",
    "version": "4.0",
    "description": "Browser extension to control video playback.",
    "permissions": ["scripting", "tabs", "storage" ],
    "host_permissions": ["file:///Users/username/*"],
    "action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "icons/playback-16.png",
        "48": "icons/playback-48.png",
        "128": "icons/playback-128.png"
      }
    },
    "icons": {
      "16": "icons/playback-16.png",
      "48": "icons/playback-48.png",
      "128": "icons/playback-128.png"
    },
    "background": {
      "service_worker": "background.js"
    },
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["content.js"]
      }
    ]
  }

Я попробовал задать вопрос в чатгпт, ссылаясь на несколько форумов, но ни один из них не помог. Мне нужно найти способ гарантировать, что функция будет запускаться только один раз при каждом вызове.

Поведение ключевого слова "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
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы повторно вводите один и тот же файл несколько раз, он запускается и каждый раз добавляет нового прослушивателя.

Решение: сначала отправьте сообщение, внедрите только в случае неудачи.

chrome.tabs.query({url: '...'}, tabs => tabs.forEach(t => send(t.id, {action: '...'})));
async function send(tabId, msg) {
  for (let i = 0; i < 2; i++) {
    try {
      return await chrome.tabs.sendMessage(tabId, msg);
    } catch (err) {
      await chrome.scripting.executeScript({
        target: { tabId },
        files: ['content.js'],
      });
    }
  }
}

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