Chrome API 都是回调型,连续使用非常不方便,希望能改成 Promise 型。Chrome 本身不提供 promisify
,不过可以自己写一个:
export default function promisify(original) {
return function (...args) {
return new Promise((resolve, reject) => {
original(...args, (...results) => {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError.message);
} else {
resolve(...results);
}
});
});
}
}
这里有几个注意事项:
- 参数使用
...args
进行拆解和合并,方便调用 - 需要检查
runtime.lastError
,不然出错的时候浏览器会报错,影响体验
使用的时候,我比较喜欢只修改需要使用的函数,不打算 promisify 全部函数,大概是这样:
import promisify from './index';
/* global chrome */
export const update = promisify(chrome.tabs.update);
export const remove = promisify(chrome.tabs.remove);
export const get = promisify(chrome.tabs.get);
// 我觉得 `close tab` 看起来更合理
export const close = remove;
// 封装一个 `goto` 的快捷方式
export const goto = function (tabId, url) {
return update(tabId, {url});
}
// 全部导入,好处是简单,坏处是不方便 tree-shaking
import * as ChromeTabs from '../chrome-promisify/chrome.tabs';
ChromeTabs.goto(tabId, 'https://blog.meathill.com');
// 需要哪个导入哪个
import {goto} from '../chrome-promisify/chrome.tabs';
goto(tabId, 'https://github.com/meathill');
欢迎吐槽,共同进步