为什么我的承诺没有返回任何价值? [英] Why is no value returned from my Promise?
问题描述
在此稍有减少的代码中,每周一次从API下载一次或多个星期的观测值,并将其汇总到rows
中并导出到CSV.至少那是个主意.实际上发生的是在exportToCsv
函数(未显示)中引发了Uncaught (in promise) TypeError: Cannot read property 'toString' of undefined
,因为从promiseArray
推送到rows
的_promise
会以undefined
的形式出现.我想念什么?
In this slightly reduced code, one or more weeks of observations are downloaded a week at a time from an API, and aggregated into rows
and exported to CSV. At least that is the idea. What is actually happening is that an Uncaught (in promise) TypeError: Cannot read property 'toString' of undefined
is raised in the (not shown) exportToCsv
function because the _promise
pushed from promiseArray
to rows
is coming out as undefined
. What am I missing?
$("#downloadBtn").click(function() {
weeks = getWeeks(startDate.val(), endDate.val()); // array like [[startDay1, endDay1], [startDay2, endDay2], ...]
// start downloading the data
var promiseArray = [];
for (i=0; i< weeks.length; i++) {
var _promise = Q.defer();
fetchDataWeek( weeks[i][0], weeks[i][1], _promise );
promiseArray.push(_promise) // Push this promise into the array
}
Promise.all(promiseArray).then( function () { // Wait for all promises to resolve
var rows = [headers];
for (i=0; i < promiseArray.length; i++) {
rows.push(promiseArray[i]);
}
exportToCsv( fileName, rows );
})
});
function fetchDataWeek( startDay, endDay, _promise ) {
url = "https://api" + startDay + endDay + ".json";
$.ajax({
url: url,
success: function(result){
var weekRows = parseHistory(result);
_promise.resolve(weekRows);
},
error: function (error) {
_promise.reject(error) // rejecting it in case of error
}
});
}
// Extract all data from a query response
function parseHistory(data) {
var weekRows = [];
var days = data.history.days;
for (var i = 0; i < days.length; i++) {
dayRows = formatDay( days[i] );
for (var j= 0; j < dayRows.length; j++) {
weekRows.push(dayRows[j]);
}
}
return weekRows;
}
推荐答案
promise不是一个神奇的对象,它在解决时会变成"一个不同的值.在执行rows.push(promiseArray[i]);
时,您是在收集承诺对象而不是它们包含的结果.
A promise is not a magical object that "becomes" a different value when it is resolved. When you were doing rows.push(promiseArray[i]);
, you were collecting promise objects not the results that they contained.
要访问已兑现或将要兑现的结果,您需要将.then(…)
回调链接到该回调,在其中可以将结果作为参数进行访问.要从数组中的所有promise收集结果,请使用Promise.all
,它会返回另一个promise,该promise不仅要等待所有输入的promise,而且还要用其结果值数组来实现.
To access the result that a promise was or will be fulfilled with, you need to chain a .then(…)
callback to it in which you can access the result as the parameter. To collect the results from all the promises in the array, you use Promise.all
, which returns another promise that not only waits for all the input promises but also fulfills with an array of their result values.
$("#downloadBtn").click(function() {
var weeks = getWeeks(startDate.val(), endDate.val());
// start downloading the data
var promiseArray = weeks.map(function(week) { // map is simpler than a loop with `push`
return fetchDataWeek( week[0], week[1] );
})
Promise.all(promiseArray).then( function(results) { // Wait for all promises to resolve
var rows = [headers].concat(results);
exportToCsv( fileName, rows );
})
});
function fetchDataWeek( startDay, endDay, _promise ) {
var url = "https://api" + startDay + endDay + ".json";
var jQpromise = $.ajax({
url: url
});
var qPromise = Q(jQpromise);
return qPromise.then(parseHistory);
}
function parseHistory(data) {
var weekRows = [];
var days = data.history.days;
for (var i = 0; i < days.length; i++) {
var dayRows = formatDay( days[i] );
for (var j= 0; j < dayRows.length; j++) {
weekRows.push(dayRows[j]);
}
}
return weekRows;
}
这篇关于为什么我的承诺没有返回任何价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!