如何使用 promise 使函数在用返回数据填充变量之前等待?
How to use promise to cause function to wait before filling variable with returned data?
我有一个 API return 的股票报价数据,我的问题是模型变量在 return_array
有数据之前首先 return 未定义。
我不确定如何使用 promises 或其他方法在填充变量之前正确等待数据(除了使用可怕的 $timeout
hack)。
您可以在 chrome 检查器中看到我的问题 (ticker_chart = undefined
):
在获取值之前,我需要 ticker_chart
等待。
调用服务以 return 股票行情数据的第一个函数:
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';
});
}
getTickerQuotes
中的函数ApiFactory
:
function getTickerQuotes(ticker) {
return $http.get('https://www.ourapi.../api/tickers/quotes/'+ticker, {cache: false});
}
我应该如何使用此处的承诺?我唯一能想到的另一件事是使用 $scope.watch 函数等待 ticker_chart
的值在尝试渲染之前发生变化。
您正在 returnTickerChartData
中创建一个承诺,但我没看到您 return 实现它。您需要将其更改为
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 在评论中提出了一个有效的观点。如果 ApiFactory.getTickerQuotes
已经 return 是一个承诺,你应该 return 而不是创建一个带有 deferred 的新承诺。还更改为使用 ApiFactory.getTickerQuotes.then()
而不是 .success()
。
我有一个 API return 的股票报价数据,我的问题是模型变量在 return_array
有数据之前首先 return 未定义。
我不确定如何使用 promises 或其他方法在填充变量之前正确等待数据(除了使用可怕的 $timeout
hack)。
您可以在 chrome 检查器中看到我的问题 (ticker_chart = undefined
):
在获取值之前,我需要 ticker_chart
等待。
调用服务以 return 股票行情数据的第一个函数:
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';
});
}
getTickerQuotes
中的函数ApiFactory
:
function getTickerQuotes(ticker) {
return $http.get('https://www.ourapi.../api/tickers/quotes/'+ticker, {cache: false});
}
我应该如何使用此处的承诺?我唯一能想到的另一件事是使用 $scope.watch 函数等待 ticker_chart
的值在尝试渲染之前发生变化。
您正在 returnTickerChartData
中创建一个承诺,但我没看到您 return 实现它。您需要将其更改为
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 在评论中提出了一个有效的观点。如果 ApiFactory.getTickerQuotes
已经 return 是一个承诺,你应该 return 而不是创建一个带有 deferred 的新承诺。还更改为使用 ApiFactory.getTickerQuotes.then()
而不是 .success()
。