【问题标题】:How to use promise to cause function to wait before filling variable with returned data?在用返回的数据填充变量之前,如何使用 promise 导致函数等待?
【发布时间】:2015-09-30 16:31:38
【问题描述】:

我有一个返回股票报价数据的 API,我的问题是模型变量在 return_array 有数据之前首先返回 undefined。

我不确定如何使用 promises 或其他方法在填充变量之前正确等待数据(除了使用可怕的$timeout hack)。


您可以在 chrome 检查器中看到我的问题 (ticker_chart = undefined):

我需要ticker_chart 等待,然后才能获得值。


第一个调用服务以返回报价数据的函数:

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

完整的服务功能:

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';
        });
}

ApiFactory 中的getTickerQuotes 函数:

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

我应该如何在这里使用承诺?我唯一能想到的另一件事是使用 $scope.watch 函数等待ticker_chart 的值发生变化,然后再尝试渲染。

【问题讨论】:

  • returnTickerChartData 只能在异步的情况下返回承诺。 renderChart 需要预见到这一点,并使用then 来代替对console.log 的同步调用。没有办法解决它。
  • 将回调函数作为第三个参数传递给returnTickerChartData函数,并在promise返回数据时使用数据调用回调。例如。 function callback(data){ ticker_chart = data;}.success(callback).
  • 你能举个例子吗?我刚试过TickerChartFactory.returnTickerChartData(ticker, limit).then(function(data) {,但得到了Cannot read property 'then' of undefined
  • 哦,等等,我忘了在我的tickerChartFactory 中返回ApiFactory 函数调用...正在取得进展

标签: javascript angularjs promise angular-promise


【解决方案1】:

您正在returnTickerChartData 中创建承诺,但我看不到您会返回它。您需要将其更改为

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

    return q.promise;
}

getTickerQuotes.success 中,您只需要使用数据来解决承诺。您不需要return ticker_chart = return_array; 行。 然后,

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

编辑:@Bergi 在 cmets 中提出了一个有效点。如果ApiFactory.getTickerQuotes 已经返回了一个promise,你应该返回它而不是创建一个带有deferred 的新promise。也改为使用ApiFactory.getTickerQuotes.then() 而不是.success()

【讨论】:

  • 最好完全避免延迟反模式。看起来getTickerQuotes 似乎已经返回了一个承诺,所以你不应该使用.success 而应该使用.then
猜你喜欢
  • 2015-03-01
  • 1970-01-01
  • 2019-05-28
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
相关资源
最近更新 更多