开发者

Is Deferring Execution in jQuery Required Here?

开发者 https://www.devze.com 2023-02-26 20:57 出处:网络
This sample code should dump a list of all bookmarks. It shows nothing in the alert but populates the list on close correctly. Without the alert, it doesn\'t build the list. Since chrome api functions

This sample code should dump a list of all bookmarks. It shows nothing in the alert but populates the list on close correctly. Without the alert, it doesn't build the list. Since chrome api functions are all asynchronous is there a "legit" way to solve this type of problem other than a timeout?

<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.js"></script>
<body>
<script>
$(document).ready(function() {

var bookmarksList ='';

chrome.bookmarks.getTree(function(bookmarks) {
    traverseBookmarks(bookmarks);
});

function traverseBookmarks(bookmarkTreeNodes) {
for(var i=0;i<bookmarkTreeNodes.length;i++) {
    if(bookmarkTreeNodes[i].url) {
        bookmarksList += '<li>Name: ' + bookmarkTreeNod开发者_运维百科es[i].title + ' ID: ' + bookmarkTreeNodes[i].id + ' URL: ' + bookmarkTreeNodes[i].url + ' Parent ID: ' + bookmarkTreeNodes[i].parentId;
        }

    if(bookmarkTreeNodes[i].children) {
        traverseBookmarks(bookmarkTreeNodes[i].children);
    } 

}
}
alert(bookmarksList);
$('#list').html(bookmarksList);
});
</script>
<ul id="list"></ul>
</body>
</html>


I'm not familiar with the Chrome extension API, but I'd hazard a guess that this is what you're looking for:

$(function() {

    function traverseBookmarks(nodes) {

        var toReturn = [],
            numNodes = nodes.length,
            node;

        for (var i = 0; i < numNodes; i++) {
            node = nodes[i];
            if (node.url) {
                toReturn.push('<li>Name: ' + node.title + ' ID: ' + node.id + ' URL: ' + node.url + ' Parent ID: ' + node.parentId + '</li>');
            }

            if (node.children) toReturn.push(traverseBookmarks(node.children));
        }

        return toReturn.join('');
    }

    chrome.bookmarks.getTree(function(bookmarks) {
        var bookmarksList = traverseBookmarks(bookmarks);
        alert(bookmarksList);
        $('#list').html(bookmarksList);
    });
});

Notes:

  • The rewritten version uses straightforward recursion, rather than using a (more-or-less) global variable.
  • I added a </li> tag, which I think you missed.
  • I used a "StringBuilder" approach rather than string concatenation, for better performance.


Ok, if we are about refactoring and we are in Chrome it can be used the native Array.prototype.forEach function and a named anonymous function for a more compact and clear code... :P

$(function(){

    chrome.bookmarks.getTree(function(bookmarks) {
        var bookmarksList = [];
        bookmarks.forEach(function me (node) {
            if (node.url) {
                bookmarksList.push('<li>Name: ' + node.title + ' ID: ' + node.id + ' URL: ' + node.url + ' Parent ID: ' + node.parentId + '</li>');
            }

            if (node.children) {
                me(node.children);
            }

        });
        $('#list').html(bookmarksList.join(''));
    });
});


I suppose you can move $('#list').html(bookmarksList); after traverseBookmarks(bookmarks); like so:

$(document).ready(function() {

    var bookmarksList ='';

    chrome.bookmarks.getTree(function(bookmarks) {
        traverseBookmarks(bookmarks);
        // ++++
        $('#list').html(bookmarksList);
    });

    function traverseBookmarks(bookmarkTreeNodes) {
        for(var i=0;i<bookmarkTreeNodes.length;i++) {
            if(bookmarkTreeNodes[i].url) {
                bookmarksList += '<li>Name: ' + bookmarkTreeNodes[i].title + ' ID: ' + bookmarkTreeNodes[i].id + ' URL: ' + bookmarkTreeNodes[i].url + ' Parent ID: ' + bookmarkTreeNodes[i].parentId;
            }

            if(bookmarkTreeNodes[i].children) {
                traverseBookmarks(bookmarkTreeNodes[i].children);
            } 

        }
    }

});

0

精彩评论

暂无评论...
验证码 换一张
取 消