1

I have difficulties with the sequence of functions in JavaScript and so far I fail to solve this by myself.

After getting a number of results provided by the Bing API, the results' titles and descriptions serve as data for further processing. As an option, I use the Yahoo Query Language to get the textual contents behind the results' URLs to increase this data.

The problem: This step takes too lang and the further processing starts before the YQL-function is done.

I am currently trying to solve this with promise & deferred like in i.e. https://stackoverflow.com/a/21524239. Is this the right approach? What am I doing wrong?

First function

/* display results with topic labels */
function displayResults(results) {
    /* ### call topicise and ensure that it is finished ### */
    var promise = topicise(results);
    promise.then(function() { 
        // further processing
    });
}

Second function

function topicise(results) {

    /* ### call generateTopics and ensure that it is finished ### */
    var deferred = $.Deferred();

    var promise = generateTopics(results);
    promise.then(function() { 
        // some code

        deferred.resolve();

        // even more code

        return deferred.promise();
    }); 
}

Third function

/* parse results for topic generation */
function generateTopics(results) {
    // TODO: ensure get(External)Content is done before processing any further!
    // https://stackoverflow.com/a/21524239 
    var deferred = $.Deferred();
    var i = 0;

    if ($("#cbDeepScan").is(':checked')) {
        var nextStep = function() {
            if (i < results.length) {
                getExternalContent(i, results[i]);
                i++;
                setTimeout(nextStep, 500); 
            } else {
                deferred.resolve();
            }
        }
        nextStep();
        return deferred.promise();
    }
    // Default: Analyze description provided by meta tags
    else {
        var nextStep = function() {
            if (i < results.length) {
                getContent(i, results[i]);
                i++;
                setTimeout(nextStep, 500); 
            } else {
                deferred.resolve();
            }
        }
        nextStep();
        return deferred.promise();      
    }
}

Best regards, Jan

Community
  • 1
  • 1
janrockt
  • 11
  • 1
  • Avoid the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572) in your `topicise` function and `return` the new promise that you get back from `.then(…)` instead, and your code will work. – Bergi Dec 05 '15 at 20:31
  • Btw, instead of repeating that whole `nextStep` thing you should just do `var doSomething = $("#cbDeepScan").is(':checked') ? getExternalContent : getContent;` and then only invoke `doSomething(i, results[i]);` – Bergi Dec 05 '15 at 20:34
  • Thank you very much, it works now. :-) – janrockt Dec 06 '15 at 16:20

0 Answers0