简体   繁体   中英

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

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 (?)

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

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM