code optimize (sendMessageAndDetect)

This commit is contained in:
2018-05-23 11:23:13 +08:00
parent fb452ef3de
commit 73482174dd
2 changed files with 56 additions and 77 deletions

View File

@ -1,6 +1,9 @@
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
if (message.from === "doExtractRequest") if (message.from === "doExtractRequest")
extract(...message.args).catch( extract(...message.args).catch(
err => console.log(err) err => {
console.log(err);
alert(err);
}
); );
}); });

View File

@ -27,13 +27,13 @@ function extract(itemsSelector, fieldSelectors, url, ...args) {
results => { results => {
data.push(...results); data.push(...results);
return redirectTab(tab, url).then( return redirectTab(tab, url).then(
tab => extractTabData(tab, itemsSelector, fieldSelectors) () => extractData(tab, itemsSelector, fieldSelectors)
); );
}, },
() => p () => p
), Promise.resolve([])); ), Promise.resolve([]));
} else { } else {
pms = extractTabData(tab, itemsSelector, fieldSelectors); pms = extractData(tab, itemsSelector, fieldSelectors);
} }
pms.then( pms.then(
results => { results => {
@ -48,108 +48,84 @@ function extract(itemsSelector, fieldSelectors, url, ...args) {
}); });
} }
function extractTabData(tab, itemsSelector, fieldSelectors) { function redirectTab(tab, url) {
let done = false; let curUrl = "";
return new Promise((resolve, reject) => { return queryUrl(tab)
chrome.tabs.sendMessage( .then(u => {
tab.id, { if (url !== u) {
from: "doExtractRequest", curUrl = u;
itemsSelector: itemsSelector, let req = {
fieldSelectors: fieldSelectors from: "doExtractGotoUrl",
}, url: url
response => { }
done = true; chrome.tabs.sendMessage(tab.id, req);
resolve(response);
} }
); })
setTimeout(() => { .then(() => queryUrl(tab, curUrl))
if (!done) reject(`extractTabData failed after 2 second.`); .then(() => reportIn(tab));
}, 2000);
});
} }
function redirectTab(tab, url) { function extractData(tab, itemsSelector, fieldSelectors) {
return new Promise((resolve, reject) => { let req = {
let req = { from: "doExtractRequest",
from: "doExtractGotoUrl", itemsSelector: itemsSelector,
url: url fieldSelectors: fieldSelectors
} }
let curUrl = ""; let failMsg = "extractTabData failed after 10 second.";
queryUrl(tab) let cond = r => !!r;
.then(u => { return sendMessageAndDetect(tab, req, cond, failMsg);
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 reportIn(tab) { function reportIn(tab) {
let req = { let req = {
from: "doExtractReportIn" from: "doExtractReportIn"
} }
return new Promise((resolve, reject) => { let failMsg = "reportIn failed after 10 second.";
let timeOut; let cond = r => r == req.from;
let rejectTimeout = setTimeout(() => { return sendMessageAndDetect(tab, req, cond, failMsg);
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);
}
});
}
});
} }
function queryUrl(tab, urlExcluded) { function queryUrl(tab, urlExcluded) {
let req = { let req = {
from: "doExtractQueryUrl" 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) => { return new Promise((resolve, reject) => {
let timeOut; let timeOut;
let rejectTimeout = setTimeout(() => { let rejectTimeout = setTimeout(() => {
reject(`queryUrl failed after 10 second.`); reject(failMsg);
clearTimeout(timeOut); clearTimeout(timeOut);
}, 10000); }, failedTimeOut);
loop(); loop();
function loop() { function loop() {
chrome.tabs.sendMessage(tab.id, req, url => { chrome.tabs.sendMessage(tab.id, req, r => {
if (url && (!urlExcluded || (urlExcluded && urlExcluded != url))) { if (cond(r)) {
resolve(url); resolve(r);
clearTimeout(rejectTimeout); clearTimeout(rejectTimeout);
} else { } else {
timeOut = setTimeout(() => { timeOut = setTimeout(() => {
loop(); loop();
}, 500); }, detectInterval);
} }
}); });
} }
}); });
} }
function createTab(url) {
return new Promise((resolve, reject) => {
chrome.tabs.create({
active: true,
url: url
}, function (tab) {
resolve(tab);
});
});
}