简体   繁体   中英

How to use promise to cause function to wait before filling variable with returned data?

I have an API which returns stock quote data, my problem is that the model variable is first returned undefined before the return_array has data.

I'm not sure how to use promises or some other method to wait for data correctly before filling the variable (besides using a terrible $timeout hack).


My problem as you can see here in the chrome inspector ( ticker_chart = undefined ):

在此处输入图片说明

I need ticker_chart to wait, before getting a value.


The first function that calls out to a service to return the ticker quote data:

function renderChart(ticker, limit) {
    ticker_chart = TickerChartFactory.returnTickerChartData(ticker, limit);
    console.log('ticker_chart = ',ticker_chart);
}

The full service function:

function returnTickerChartData(ticker, limit) {

    var q = $q.defer();

    var get_data = '';
    if (limit > 0) {
        get_data = '?limit=' + limit;
    }

    ApiFactory.getTickerQuotes(ticker.ticker).success(
        function(data, status, headers, config) {
            if (data.status == 'Success') {
                console.log('REST GET Ticker Chart', 'success');
                var data_array = [];

                for (var i=0; i<data.quotes.length; i++) {
                    data_array.push([data.quotes[i].start_epoch, data.quotes[i].price]);
                }

                var return_array = [{
                    "area": true,
                    "key": "Price",
                    "color": '#BFBFBF',
                    "values": data_array
                }];

                console.log('return_array = ',return_array);
                console.log('q =',q);
                q.resolve(return_array);
                return ticker_chart = return_array;

            } else {
                console.log('failed to REST GET Ticker Chart');
                q.reject('failed to REST GET Ticker Chart');
                return ticker_chart = 'failed to REST GET Ticker Chart';
            }
        }).error(function(data, status) {
            console.log('error in getting REST GET Ticker Chart');
            q.reject('error in getting REST GET Ticker Chart');
            return ticker_chart = 'error in getting REST GET Ticker Chart';
        });
}

The getTickerQuotes function in the ApiFactory :

function getTickerQuotes(ticker) {
    return $http.get('https://www.ourapi.../api/tickers/quotes/'+ticker, {cache: false});
}

How should I be using the promise here? The only other thing I can think of is using a $scope.watch function to wait till the value of ticker_chart changes before trying to render something.

Your are creating a promise in returnTickerChartData but I don't see you ever returning it. You need to change it to be

function returnTickerChartData(ticker, limit) {
    var q = $q.defer();
    // API call

    return q.promise;
}

In getTickerQuotes.success you just need to resolve the promise with the data. You don't need the line return ticker_chart = return_array; . And then,

function renderChart(ticker, limit) {
    TickerChartFactory.returnTickerChartData(ticker, limit)
        .then(function (result) {
            ticker_chart = result;
            console.log('ticker_chart = ', ticker_chart);
        });
}

EDIT: @Bergi raises a valid point in the comments. If ApiFactory.getTickerQuotes already returns a promise, you should return that instead of creating a new promise with deferred. Also change to using ApiFactory.getTickerQuotes.then() instead of .success() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM