Chrome API 都是回调型,连续使用非常不方便,希望能改成 Promise 型。Chrome 本身不提供 promisify
,不过可以自己写一个:
chrome-promisifyexport 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 全部函数,大概是这样:
chrome.tab.jsimport 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}); }
app.js// 全部导入,好处是简单,坏处是不方便 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');
欢迎吐槽,共同进步