How to fix my promise return here for this functio

2019-08-10 21:27发布

问题:

I have an array of tags which may contain up to 3 items.

Next I pass tags into my getTagQuotes function and am trying to set a promise variable to it. Right now I'm getting promise is undefined.

// If there are tags, the wait for promise here:
if (tags.length > 0) {
    var promise = getTagQuotes(tags).then(function() {
        console.log('promise =',promise);

        for (var i=0; i<tweetArrayObjsContainer.length; i++) {
            chartObj.chartData.push(tweetArrayObjsContainer[i]);
        }

        chartDirective = ScopeFactory.getScope('chart');
        chartDirective.nvd3.drawChart(chartObj.chartData);
    });
}
else {
    chartDirective = ScopeFactory.getScope('chart');
    chartDirective.nvd3.drawChart(chartObj.chartData);
}

^ The goal above is to make sure that arrays in tweetArrayObjsContainer have been filled and pushed into chartObj.chartData before I draw my nvd3 chart.

Below is my getTagQuotes function which does another loop through the tags (up to 3) and calls another service GetTweetVolFactory.returnTweetVol which makes the actual API call to retrieve data.

I have code which checks if the we're on the final loop step, then calls the formatTagData function.

Inside formatTagData is where I fill the tweetArrayObjsContainer.

// Check for and GET tag data:
////////////////////////////////////////////////////////////////////
function getTagQuotes(tags) {
    console.log('getTagQuotes called with',tags);
    var deferred   = $q.defer(); // <- setting $q.defer here
    var url        = 'app/api/social/twitter/volume/';

    for (var i=0; i<tags.length; i++) {
        var loopStep = i;
        rawTagData   = [];

        GetTweetVolFactory.returnTweetVol(url+tags[i].term_id)
            .success(function(data, status, headers, config) {
                rawTagData.push(data);

                if (loopStep === (rawTagData.length - 1)) {
                    // formatTagData fills the tweetArrayObjsContainer with data:
                    formatTagData(rawTagData);
                    deferred.resolve(); // <-- last step, so resolve
                    return deferred.promise;
                }
            })
            .error(function(data, status) {
                return 'error in returning tweet data';
            });
    }

    function formatTagData(rawData) {
        tweetArrayObjsContainer = [];

        for (var i=0; i<rawData.length; i++) {
            var data_array = [];
            var loopNum = i;

            _(rawData[i].frequency_counts).reverse().value();

            for (var j=0; j<rawData[loopNum].frequency_counts.length; j++) {
                var data_obj = {};
                rawData[loopNum].frequency_counts[j].start_epoch = addZeroes(rawData[loopNum].frequency_counts[j].start_epoch);
                data_obj.x = rawData[loopNum].frequency_counts[j].start_epoch;
                data_obj.y = rawData[loopNum].frequency_counts[j].tweets;
                data_array.push(data_obj);
            }

            var tweetArrayObj = {
                "key"    : "Quantity"+(i+1),
                "type"   : "area",
                "yAxis"  : 1,
                "color"  : tagColorArray[i],
                "values" : data_array
            };

            tweetArrayObjsContainer.push(tweetArrayObj);
        }
    }
}

回答1:

Your getTagQuotes function should return a promise with the $q service, check it out.

It should look like this:

function getTagQuotes(tags) {
    var deferred = $q.defer();

    (...)
    // When the action is finished here, call resolve:
    deferred.resolve();
    (...)

    // And in the end, return the promise
    return deferred.promise;
}

And finally, in your main code, you'll do:

var promise = getTagQuotes(tags).then(function(){
    console.log('promise =',promise);
    // Fill chartObj with tweet data arrays
    (...)
});


回答2:

This function has no return statement.

function getTagQuotes(tags)