From 73482174dd21f65c5204f5dfc6bf4557f79866ff Mon Sep 17 00:00:00 2001 From: jebbs Date: Wed, 23 May 2018 11:23:13 +0800 Subject: [PATCH] code optimize (sendMessageAndDetect) --- scripts/background.js | 5 +- scripts/extract.js | 128 +++++++++++++++++------------------------- 2 files changed, 56 insertions(+), 77 deletions(-) diff --git a/scripts/background.js b/scripts/background.js index 50c0709..294ee46 100644 --- a/scripts/background.js +++ b/scripts/background.js @@ -1,6 +1,9 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { if (message.from === "doExtractRequest") extract(...message.args).catch( - err => console.log(err) + err => { + console.log(err); + alert(err); + } ); }); \ No newline at end of file diff --git a/scripts/extract.js b/scripts/extract.js index 2d01c9b..7fe670e 100644 --- a/scripts/extract.js +++ b/scripts/extract.js @@ -27,13 +27,13 @@ function extract(itemsSelector, fieldSelectors, url, ...args) { results => { data.push(...results); return redirectTab(tab, url).then( - tab => extractTabData(tab, itemsSelector, fieldSelectors) + () => extractData(tab, itemsSelector, fieldSelectors) ); }, () => p ), Promise.resolve([])); } else { - pms = extractTabData(tab, itemsSelector, fieldSelectors); + pms = extractData(tab, itemsSelector, fieldSelectors); } pms.then( results => { @@ -48,108 +48,84 @@ function extract(itemsSelector, fieldSelectors, url, ...args) { }); } -function extractTabData(tab, itemsSelector, fieldSelectors) { - let done = false; - return new Promise((resolve, reject) => { - chrome.tabs.sendMessage( - tab.id, { - from: "doExtractRequest", - itemsSelector: itemsSelector, - fieldSelectors: fieldSelectors - }, - response => { - done = true; - resolve(response); +function redirectTab(tab, url) { + let curUrl = ""; + return queryUrl(tab) + .then(u => { + if (url !== u) { + curUrl = u; + let req = { + from: "doExtractGotoUrl", + url: url + } + chrome.tabs.sendMessage(tab.id, req); } - ); - setTimeout(() => { - if (!done) reject(`extractTabData failed after 2 second.`); - }, 2000); - }); + }) + .then(() => queryUrl(tab, curUrl)) + .then(() => reportIn(tab)); } -function redirectTab(tab, url) { - return new Promise((resolve, reject) => { - let req = { - from: "doExtractGotoUrl", - url: url - } - let curUrl = ""; - queryUrl(tab) - .then(u => { - if (url !== u) { - curUrl = u; - chrome.tabs.sendMessage(tab.id, req); - } - }) - .then(() => queryUrl(tab, curUrl)) - .then(() => reportIn(tab)) - .then(tab => resolve(tab)) - .catch(err => reject(err)); - }); +function extractData(tab, itemsSelector, fieldSelectors) { + let req = { + from: "doExtractRequest", + itemsSelector: itemsSelector, + fieldSelectors: fieldSelectors + } + let failMsg = "extractTabData failed after 10 second."; + let cond = r => !!r; + return sendMessageAndDetect(tab, req, cond, failMsg); } function reportIn(tab) { let req = { from: "doExtractReportIn" } - return new Promise((resolve, reject) => { - let timeOut; - let rejectTimeout = setTimeout(() => { - reject(`reportIn failed after 10 second.`); - clearTimeout(timeOut); - }, 10000); - loop(); - - function loop() { - chrome.tabs.sendMessage(tab.id, req, r => { - if (r == req.from) { - resolve(tab); - clearTimeout(rejectTimeout); - } else { - timeOut = setTimeout(() => { - loop(); - }, 500); - } - }); - } - }); + let failMsg = "reportIn failed after 10 second."; + let cond = r => r == req.from; + return sendMessageAndDetect(tab, req, cond, failMsg); } function queryUrl(tab, urlExcluded) { let req = { from: "doExtractQueryUrl" } + let failMsg = "queryUrl failed after 10 second."; + let cond = url => url && (!urlExcluded || (urlExcluded && urlExcluded != url)); + return sendMessageAndDetect(tab, req, cond, failMsg); +} + +/** + * Repeatedly sending a message to target tab until the response is detected good. + * The response is returned with the Promise. + * @param {chrome.tab} tab the table where to send the message + * @param {object} req the request data. + * @param {function} cond success condition function, r:any=>boolean + * @param {string} failMsg message when failed after time out + * @param {number} failedTimeOut fail time out + * @param {number} detectInterval interval for detecting + */ +function sendMessageAndDetect(tab, req, cond, failMsg, failedTimeOut, detectInterval) { + failedTimeOut = failedTimeOut || 10000; + detectInterval = detectInterval || 500; return new Promise((resolve, reject) => { let timeOut; let rejectTimeout = setTimeout(() => { - reject(`queryUrl failed after 10 second.`); + reject(failMsg); clearTimeout(timeOut); - }, 10000); + }, failedTimeOut); loop(); function loop() { - chrome.tabs.sendMessage(tab.id, req, url => { - if (url && (!urlExcluded || (urlExcluded && urlExcluded != url))) { - resolve(url); + chrome.tabs.sendMessage(tab.id, req, r => { + if (cond(r)) { + resolve(r); clearTimeout(rejectTimeout); } else { timeOut = setTimeout(() => { loop(); - }, 500); + }, detectInterval); } }); } }); -} - -function createTab(url) { - return new Promise((resolve, reject) => { - chrome.tabs.create({ - active: true, - url: url - }, function (tab) { - resolve(tab); - }); - }); } \ No newline at end of file