chrome书签中的递归与回调函数

时间:2015-08-22 17:11:25

标签: javascript google-chrome recursion google-chrome-extension callback

我正在尝试使用chrome书签api编写一个函数来创建一组分层的书签。我可以通过递归函数遍历树。

但是在创建书签时,由于API的异步性质,这将无效。 chrome.bookmarks.create(object bookmark, function callback())将书签节点数据作为第一个参数,将回调函数作为第二个参数;该回调是您获得新节点(api reference)的ID的地方。

我的层次结构有这个数据结构:

var newbookmarks = [
    { title: 'bookmark1',
      url: 'foo.com'
      submenu: []
    },
    { title: 'Submenu1',
      submenu: [
        { title: 'bookmark1.1',
          url: 'bar.org',
          submenu: []
        },
        { title: 'bookmark1.2',
          url: 'baz.com',
          submenu: []
        }
      ]
    },
    { title: 'bookmark2',
      url: 'bletch.edu',
      submenu: []
    }
];

它是一个节点对象数组,每个节点对象都有一个子菜单元素,它本身可以是一个节点对象数组。

我首先想到的是递归创建层次结构,就像遍历函数一样:

createBookmarkNodes(parentid, bookmarks) {
  var i,newnode;
  for (i=0; i<bookmarks.length; i++) {
    newnode = chrome.bookmarks.create({parentId: parentid, title: bookmarks[i].title, url: bookmarks[i].url});
    if (bookmarks[i].submenu.length > 0) {
      createBookmarkNodes(newnode.id, bookmarks[i].submenu);
    }
  }
}

这不起作用,因为create不会返回子菜单的父ID所需的节点,直到你进入回调才能找到它。但是一旦进入回调,我就不知道我在新书标记数据结构中的位置。

function installBookmarkNodes(parentid, bookmarks) {
    var i;
    for (i=0; i<bookmarks.length, i++) {
        chrome.bookmarks.create({parentId: parentid, title: bookmarks[i].title, url: bookmarks[i].url}, create_callback);
    }
}
function create_callback(bookmarkobj) {
    var child-nodes-of-this-bookmark = ???;
    for (child-nodes-of-this-bookmark) {
        chrome.bookmarks.create({parentId: bookmarkobj.parentId, title: ???, url: ???}, create_callback);
    }
}

如何在回调范例中的新书签数据结构中保留我的位置?

1 个答案:

答案 0 :(得分:1)

只需将递归调用移动到回调中:

createBookmarkNodes(parentid, bookmarks) {
    bookmarks.forEach(function(bm) {
        chrome.bookmarks.create({
            parentId: parentid,
            title: bm.title,
            url: bm.url
        }, function(result) {
            if (bm.submenu && bm.submenu.length > 0) {
                createBookmarkNodes(result.id, bm.submenu);
            }
        });
    });
}