Maison >interface Web >js tutoriel >Pourquoi « sendResponse() » n'attend-il pas les fonctions asynchrones dans l'écouteur « onMessage » de Chrome ?

Pourquoi « sendResponse() » n'attend-il pas les fonctions asynchrones dans l'écouteur « onMessage » de Chrome ?

DDD
DDDoriginal
2024-11-22 16:29:14749parcourir

Why Doesn't `sendResponse()` Wait for Asynchronous Functions in Chrome's `onMessage` Listener?

"sendResponse" N'attend pas la fonction asynchrone ou la résolution de la promesse

Introduction

Lors de l'envoi d'un message depuis popup.js à contentscript.js, le La fonction sendResponse() devrait attendre la fin de la fonction getThumbnails(). Cependant, dans ce scénario, sendResponse() n'attend pas, ce qui entraîne des problèmes d'asynchronicité.

Explication du problème

Le principal problème est que Chrome ne prend toujours pas en charge les promesses dans la valeur renvoyée par les écouteurs onMessage. dans les manifestes V2 et V3. Par conséquent, lorsque votre écouteur déclare le mot-clé async, il renvoie une promesse au lieu de la valeur vraie littérale requise par onMessage. Cela entraîne l'ignorance de la promesse renvoyée, ce qui entraîne la fermeture prématurée du canal de messagerie.

Solution : Rendre l'écouteur compatible

Pour garantir la compatibilité avec l'implémentation actuelle de Chrome, vous pouvez supprimer le mot clé async d'avant les paramètres de la fonction (request, sender, sendResponse) et déclarez une fonction asynchrone distincte pour gérer le traitement des messages :

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.message === "get_thumbnails") {
    processMessage(msg).then(sendResponse);
    return true; // keep the messaging channel open for sendResponse
  }
});

async function processMessage(msg) {
  console.log('Processing message', msg);
  // ... asynchronous processing code
  return 'foo';
}

Corriger l'API pour Autoriser l'écouteur asynchrone/promise

Vous pouvez également patcher l'API pour autoriser les écouteurs asynchrones/promises en ajoutant le code suivant à chaque script à l'aide de chrome.runtime.onMessage :

if ('crbug.com/1185241') { // replace with a check for Chrome version that fixes the bug
  const {onMessage} = chrome.runtime, {addListener} = onMessage; 
  onMessage.addListener = fn => addListener.call(onMessage, (msg, sender, respond) => {
    const res = fn(msg, sender, respond);
    if (res instanceof Promise) return !!res.then(respond, console.error);
    if (res !== undefined) respond(res);
  });
}

Avec le patch appliqué, vous pouvez renvoyer la valeur directement :

chrome.runtime.onMessage.addListener(async msg => {
  if (msg === 'foo') {
    const res = await fetch('https://foo/bar');
    const payload = await res.text();
    return {payload};
  }
});

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:L'évolution de JavaScriptArticle suivant:L'évolution de JavaScript