Warm tip: This article is reproduced from stackoverflow.com, please click
google-chrome-extension javascript

Recursively loop through node tree and check if a node exists, if not, create it using callback or p

发布于 2020-04-13 10:32:16

I want to write a function that recursively browses a node tree and depending on if a certain node exists, either log its values or create the missing node. This should be fairly simple but I can't seem to wrap my head around it.

my code currently looks like this:

let folderName = 'My Folder Name';

function init() {
  let hasFolder = false;
  let folderId = '';

  chrome.bookmarks.getTree(function(itemTree){
    itemTree.forEach(function(item){
      processNode(item);
    });
  });

  function processNode(node) {
    // recursively process child nodes
    if (node.children) {
      node.children.forEach(function(child) { 
        processNode(child); 
      });
    }

    if (node.title == folderName) { 
      console.log(folderName + ' folder already exists: ID is ' + node.id);
      hasFolder = true;
      folderId = node.id;
    }
  }
}

It's working fine for outputting the node ID if the folder already exists, but now I want it to create the folder if it doesn't. I figured I'd need to use a promise or callback. The code to create the folder is simple:

function createFolder() {
  chrome.bookmarks.create({
    title: appName,
    url: null
  }, onBookmarkAdded)
}

How and where would I integrate that into my current function? (init() is called on first install of the app.)

Questioner
bruno
Viewed
25
Brian S 2020-02-04 00:50

It seems like you should be able to check the value of hasFolder in the callback and add the folder if necessary. Something like this:

chrome.bookmarks.getTree(function(itemTree){

  itemTree.forEach(function(item){
    processNode(item);
    if(hasFolder) return;
  });

  if(!hasFolder){
    createFolder();
  }
});

I'm not familiar with Chrome's bookmarks api, so I can't say if it will complain about you modifying the bookmarks collection inside of the getTree callback, but if not, this approach should work.

Also, a side note, in order to make it more efficient, you may want to return out of the forEach once you find the folder, so as to reduce unnecessary loops (already added in the above code).

function processNode(node) {
  // recursively process child nodes
  if (node.children) {
    node.children.forEach(function(child) { 
      processNode(child); 
      if(hasFolder) return;
    });
  }

  if (node.title == folderName) { 
    console.log(folderName + ' folder already exists: ID is ' + node.id);
    hasFolder = true;
    folderId = node.id;
  }

}