Tuesday, May 21, 2024
65
rated 0 times [  67] [ 2]  / answers: 1 / hits: 37229  / 7 Years ago, thu, november 2, 2017, 12:00:00

I wrote a chrome extension, popup js will send a message to background and background will redirect the message to content script, after some network request, the result should be returned to the background and then popup js.



Below are some simplified pieces of my code.



popup js



$('.porintButton').click(function() {
switch (this.id) {
case 'learningPointButton':
chrome.runtime.sendMessage({ action: 'learning' }, callback);
processResult();
break;
}
return true;
});


backgound js



chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, request, response => {
if (chrome.runtime.lastError) {
// If I click learningPointButton, the line will excute, and log 'ERROR: {message: Could not establish connection. Receiving end does not exist.}'
console.log('ERROR: ', chrome.runtime.lastError);
} else {
console.log('The Content Script got the following Message: ' + JSON.stringify(response));
sendResponse(response);
}
});
});
return true;
});


content script



chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
console.info('contentscript', request, sender);
switch (request.action) {
case 'learning':
// this simulate network async request, will not work,
setTimeout(() => {
sendResponse({ action: request.action, result: 'ok' });
}, 0);
// this works
// sendResponse({ action: request.action, result: 'ok' });
break;
}
// I have read https://developer.chrome.com/extensions/messaging#simple and return true here
return true;
});


If I change the message tunnel to the Long-lived connections, it will work, why?


More From » google-chrome

 Answers
35

@wOxxO Thanks, you are right.



I rewrite the code using Promise style, and it works now.



my rewritten code like this.



chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.info('contentscript', request, sender);
switch (request.action) {
case 'learning':
Promise.all([doLearning(), doLearning(), doLearning()])
.then(unusedData => {
return getScore();
})
.then(scores => {
console.info(scores);
sendResponse({ action: request.action, result: 'ok', scores: scores });
})
.catch(e => {
console.error(e);
sendResponse({ action: request.action, result: 'error', message: e });
});
break;
case 'score':
getScore().then(scores => {
console.info(scores);
sendResponse({ action: request.action, result: 'ok', scores: scores });
}).catch(e => {
console.error(e);
sendResponse({ action: request.action, result: 'error', message: e });
});
break;
}
return true;
});


And I can send message from popup to contentscript directly.


[#56037] Monday, October 30, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
samarab

Total Points: 620
Total Questions: 95
Total Answers: 89

Location: Bonaire
Member since Wed, May 11, 2022
2 Years ago
;