问题
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