0

Im using the wait.for library to get rid of some asynchronous calls. Im doing this because I don't really care much about having my server run efficiently or anything, I'm using node.js for some data processing using the Natural NLP npm module.

Anyways, Im recursively building a tree and requesting an wikipedia article for each node. That wikipedia request is asynchronous and I am trying to make it synchronous via a call to wait.for(...). The request works fine if the recursive call ends after just one activation, but throws an error if the recursion carries on any further.

Visually, I mean

 [ROOT]
 /  | \
[] [] [] <--- This level is fine ... No Errors
|
[]       <--- Error Here, on level 2

The error is:

/Users/me/Documents/Node Projects/Personal Website/node_modules/wait.for/waitfor.js:37
                                fiber.run();   //resume fiber after "yield"
                                      ^
TypeError: Cannot call method 'toString' of undefined
    at TfIdf.tfidf (/Users/me/Documents/Node Projects/Personal Website/node_modules/natural/lib/natural/tfidf/tfidf.js:132:42)
    at isIrrelevant (/Users/me/Documents/Node Projects/Personal Website/finalproject/wikitree.js:126:47)

Here is the code for the recursive call:

var WikiTree = function(node) {
    this.name    = node.name;
    this.context = node.context;
    this.text    = node.article;

    if (node.children) {
        this.children = node.children;
    }

    function createArticleSummary(article) {
        // TODO: Must Implement
        return article;
    }

    function isIrrelevant(article, title, linkText) {
        // Tweak Here
        var articleTfIdf = new TfIdf();
        articleTfIdf.addDocument(article);

        var titleRelevanceToArticle = articleTfIdf.tfidf(title,0); // ERROR HERE: This is wikitree.js:126
        var textRelevanceToArticle = articleTfIdf.tfidf(linkText,0);

        var titleRelevanceToZen = zenTfidf.tfidf(title,0);
        var textRelevanceToZen = zenTfidf.tfidf(linkText,0);

        return ( titleRelevanceToZen / titleRelevanceToArticle >= 1 ) || ( textRelevanceToZen / textRelevanceToArticle >= 1 );

    }

    WikiTree.prototype.searchChild = function(child) {
        console.log("Searching for Link Title \"" + child.title + "\" And Link Text \"" + child.linkText + "\"");

        var childQuery = {
            query : child.title,
            format : "html",
            summaryOnly : false
        };

        var childArticle = wait.for(wikipedia.searchArticle, childQuery);
        console.log("Got Wikipedia Response for " + child.title);

        var childWikiLinks = extractLinkedWikis(childArticle);

        console.log("Found " + childWikiLinks.length + " Links for " + child.title);
        for (var i = childWikiLinks.length - 1; i >= 0; i--) {
            if ( LinkTrie.contains(childWikiLinks[i].title) || LinkTrie.contains(childWikiLinks[i].linkText) ) {
                childWikiLinks.splice(i,1);
            } else if ( isIrrelevant( childWikiLinks[i] ) ) {
                childWikiLinks.splice(i,1);
            } else {
                LinkTrie.addStrings([ childWikiLinks[i].title, childWikiLinks[i].text ]);
            }
        };

        console.log("After pruning, " + childWikiLinks.length + " Links left for " + child.title);

        var newChildWT = new WikiTree({
            name : child.title,
            context : child.linkText,
            article : childArticle,
            children : createArticleSummary(childWikiLinks)
        });

        return newChildWT;

    };

    WikiTree.prototype.descend = function() {
        // Descend to the next level ... Meaning find the children of the current children (If there are any)
        if (!this.children) {
            console.log("Leaf at " + this.name);
            return;
        }

        for (var i = this.children.length - 1; i >= 0; i--) {
            if ( this.children[i].title.match(/Category:/) ) {
                console.log("Found 'Category:' at " + i + " in " + this.children[i].title);
                this.children.splice(i,1);
            } else
                this.children[i] = this.searchChild(this.children[i]);
        };
        console.log("Done With Descend For " + this.name);
    };

    this.descend();
};

var result = ...; // A String
var zenLinks = ...; // An Array of objects
// Actually make the first recursive call here
var zenTree = new WikiTree({
    name : 'Zen & The Art of Motorcycle Maintenance',
    article : result,
    children : zenLinks
});

Anyways, any help will be much appreciated. There wasn't much help from googling the issue so anyone that has had experience with either wait.for or node fibers could greatly help me out.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
sourdesi
  • 360
  • 1
  • 4
  • 21
  • Helll, did you try my answer. Does it satisfy your question? – Inanc Gumus Jul 13 '14 at 17:42
  • Have you solved the problem? can you paste the code at: at TfIdf.tfidf (/Users/me/Documents/Node Projects/Personal Website/node_modules/natural/lib/natural/tfidf/tfidf.js:132:42)? – Lucio M. Tato Aug 26 '14 at 01:54

1 Answers1

0

I think you might do this:

var childArticle = wait.forMethod(wikipedia, 'searchArticle', childQuery);

Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101