JS Promise when looping trough array

1127 views javascript
6

I'm developing a google chrome extension and I have to loop trough the nodes (folders) to check how many items I have within each folder. I'm suppling an item ID to the function getBookmarksCount(ID). I'm having an issue to get a result from the main function the console.log() returns correct value at the point of logging.

Here is my code:

const getBookmarksCount = (bmkNode) => {
    let nodes = []
    let result = 0

    new Promise ((resolve, reject) => {
        chrome.bookmarks.getChildren(bmkNode, (bmkChildren) => {

            _.each(bmkChildren, (item) => {
            
                // Check if the item is a bookmark link
                if (!(item.url === undefined || item.url === null)) {
                    nodes.push(item.title)
                }
                
            })
    
            resolve(_.size(nodes))

        })
        
    }).then((size) => {
        console.log(size) //The correct number of items is listed here eg. 6
        result = size
    })

    return result
}

//I'm suppling a parent folder ID the function should return number of children

getBookmarksCount(123) // eg. 6 -> at the moment returns 0

answered question

Promises imply asynchronous code - you are not waiting for asynchronous code to complete before you return result

chrome.bookmarks.getChildren is an async function so I'm trying fo wrap it in promise...How to improve my code?

1 Answer

13

As pointed out by Bravo in the comments, you are not really waiting for your code to execute. You are ever so close, though!

const getBookmarksCount = (bmkNode) => {
   return new Promise ((resolve) => {
      let nodes = []
      chrome.bookmarks.getChildren(bmkNode, (bmkChildren) => {
          _.each(bmkChildren, (item) => {
              // Check if the item is a bookmark link
              if (!(item.url === undefined || item.url === null)) {
                  nodes.push(item.title)
              }  
          })

          resolve(_.size(nodes))
      })
   })
}
getBookmarksCount(123).then(size => {
    console.log(size)
})

Note the return new Promise on the second line, which is a key difference from your provided snippet. By doing this, you wait to "return" here until you actually finish the async work and call resolve. Then, to get the value returned, you would do the same .then syntax you used but at the call of getBookmarksCount.

Hopefully that helps and, of course, also works!

posted this

Have an answer?

JD

Please login first before posting an answer.