Javascript (typescript) Chrome extension, function callback as promises?

这一生的挚爱 提交于 2020-01-13 14:04:06

问题


for a code like this

let anotherFolder='whatever';
let anotherFolder2='whatever';

chrome.bookmarks.create( {title:'whatever2'}, function( parentFolder ) {
  chrome.bookmarks.move( anotherFolder, {parentId: parentFolder.id}, function() {
    chrome.bookmarks.removeTree( anotherFolder2, function() {
      resolve();
    });
  });
});

can I transform it to chain functions? Something like

let anotherFolder='whatever';
let anotherFolder2='whatever';

return new Promise(function(resolve){
  chrome.bookmarks.create( {title:'whatever2'}, function( parentFolder ) {
    resolve(parentFolder);
  }).then( (parentFolder) => {
    chrome.bookmarks.move( anotherFolder, {parentId: parentFolder.id}, function() {
      resolve();
    })
  }).then () => {
    chrome.bookmarks.removeTree( anotherFolder2, function() {
      resolve();
    });
  });
});

Because I get the error of 'Property 'then' does not exist on type 'void'.'

*this is javascript-typescript, but it shouldn't matter here (?)


回答1:


You'll need to "promisify" any chrome.bookmarks.* functions - this, incidently, makes them work the same as browser.bookmarks.* functions in Firefox and (eventually) Edge Web Extensions

Promisifying the functions you use

let create = p1 => new Promise((resolve, reject) => {
    chrome.bookmarks.create(p1, resolve);
});
let move = (p1, p2) =>  new Promise((resolve, reject) => {
    chrome.bookmarks.move(p1, p2, resolve);
});
let removeTree = p1 => new Promise((resolve, reject) => {
    chrome.bookmarks.removeTree(p1, resolve);
});

Then you can use these functions as follows:

let anotherFolder='whatever';
let anotherFolder2='whatever';


create({title:'whatever2'})
.then(parentFolder => move(anotherFolder, {parentId: parentFolder.id}))
.then(() => removeTree(anotherFolder));

If you are thinking of having your extension available in Firefox (and eventually Edge)

not tested

let create = browser.bookmarks.create || p1 => new Promise((resolve, reject) => {
    chrome.bookmarks.create(p1, resolve);
});
let move = browser.bookmarks.move || (p1, p2) => new Promise((resolve, reject) => {
    chrome.bookmarks.move(p1, p2, resolve);
});
let removeTree = browser.bookmarks.removeTree || p1 => new Promise((resolve, reject) => {
    chrome.bookmarks.removeTree(p1, resolve);
});

Then your code above should work in any Web Extension




回答2:


The accepted answer is good, but there are libraries that already do this for you, such as chrome-extension-async. That also includes TypeScript definitions for the promisified callbacks.

Install it with bower

bower install chrome-extension-async

Or npm

npm i chrome-extension-async

Or download chrome-extension-async.js file and include it directly:

<script type="text/javascript" src="chrome-extension-async.js"></script>

You can use this library with promises, which allows you to chain functions (rather than nest callbacks):

function whatever(anotherFolder, anotherFolder2) {
    return  chrome.bookmarks.create({title:'whatever2'}).
        then(parentFolder => 
            chrome.bookmarks.move(anotherFolder, {parentId: parentFolder.id})).
        then(() => 
            chrome.bookmarks.removeTree(anotherFolder2));
}

I strongly recommend that you use the (fairly new) async and await syntax, and TypeScript can transpile it to older versions of JS if you want. Then your code becomes:

async function whatever(anotherFolder, anotherFolder2) {
    const parentFolder = await chrome.bookmarks.create({title:'whatever2'});
    await chrome.bookmarks.move(anotherFolder, {parentId: parentFolder.id});
    await chrome.bookmarks.removeTree(anotherFolder2);
}

This does the same thing as the promise based code, but bubbles exceptions up and make it easier to use with logic flow (if branching logic can be messy even with promises).



来源:https://stackoverflow.com/questions/43223641/javascript-typescript-chrome-extension-function-callback-as-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!