How do I use promises in a Chrome extension?

陌路散爱 提交于 2020-06-22 02:59:07

问题


What I am trying to do is create a chrome extension that creates new, nested, bookmark folders, using promises.

The function to do this is chrome.bookmarks.create(). However I cannot just loop this function, because chrome.bookmarks.create is asynchronous. I need to wait until the folder is created, and get its new ID, before going on to its children.

Promises seem to be the way to go. Unfortunately I cannot find a minimal working example using an asynchronous call with its own callback like chrome.bookmarks.create.

I have read some tutorials 1, 2, 3, 4. I have searched stackOverflow but all the questions do not seem to be about plain vanilla promises with the chrome extension library.

I do not want to use a plugin or library: no node.js or jquery or Q or whatever.

I have tried following the examples in the tutorials but many things do not make sense. For example, the tutorial states:

The promise constructor takes one argument—a callback with two parameters: resolve and reject.

But then I see examples like this:

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

How this works is a mystery to me.

Also, how can you call resolve() when its never been defined? No example in the tutorials seem to match real life code. Another example is:

function isUserTooYoung(id) {
   return openDatabase() // returns a promise   
.then(function(col) {return find(col, {'id': id});})

How do I pass in col, or get any results!

So if anyone can give me a minimal working example of promises with an asynchronous function with its own callback, it would be greatly appreciated.

SO wants code, so here is my non-working attempt:

//loop through all
function createBookmarks(nodes, parentid){  

  var jlen = nodes.length;
  var i;
  var node;
  for(var i = 0; i < nodes.length; i++){
        var node = nodes[i];

        createBookmark(node, parentid);
  }
}

//singular create
function createBookmark(node, parentid){  
      var bookmark = { 
    parentId : parentid,
    index : node['index'],
    title : node['title'],
    url : node['url']
  }

  var callback = function(result){
    console.log("creation callback happened.");
    return result.id;  //pass ID to the callback, too
  }

    var promise = new Promise(function(resolve, reject) {

        var newid = chrome.bookmarks.create(bookmark, callback)

      if (newid){
        console.log("Creating children with new id: " + newid);
        resolve( createBookmarks(bookmark.children, newid));
      }

    });
}

//allnodes already exists
createBookmarks(allnodes[0],"0");

Just doesn't work. The result from the callback is always undefined, which it should be, and I do not see how a promise object changes anything. I am equally mystified when I try to use promise.then().

var newid = promise.then(  //wait for a response?
            function(result){
            return chrome.bookmarks.create(bookmark, callback); 
            }
        ).catch(function(error){
            console.log("error " + error);
        });  

        if (node.children) createBookmarks(node.children, newid);

Again, newid is always undefined, because of course bookmarks.create() is asynchronous.

Thank you for any help you can offer.


回答1:


Honestly, you should just use the web extension polyfill. Manually promisifying the chrome APIs is a waste of time and error prone.

If you're absolutely insistent, this is an example of how you'd promisify chrome.bookmarks.create. For other chrome.* APIs, you also have to reject the callback's error argument.

function createBookmark(bookmark) {
  return new Promise(function(resolve, reject) {
    try {
      chrome.bookmarks.create(bookmark, function (result) {
        if (chrome.runtime.lastError) reject(chrome.runtime.lastError)
        else resolve(result)
      })
    } catch (error) {
      reject(error)
    }
  })
}


createBookmark({})
  .then(function (result) {
     console.log(result)
   }).catch(function (error) {
     console.log(error)
   })

To create multiple bookmarks, you could then:

function createBookmarks(bookmarks) {
  return Promise.all(
    bookmarks.map(function (bookmark) {
      return createBookmark(bookmark)
    })
  )
}

createBookmarks([{}, {}, {}, {}])
  .catch(function (error) {
    console.log(error)
  })


来源:https://stackoverflow.com/questions/50844405/how-do-i-use-promises-in-a-chrome-extension

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