为什么我的承诺没有返回任何价值?
在这个稍微减少的代码中,一周一次从API下载一周或多周的观察,并聚合rows
并导出到CSV。 至少这是个主意。 实际发生的是Uncaught (in promise) TypeError: Cannot read property 'toString' of undefined
在(未显示) exportToCsv
函数中引发,因为从_promise
推送到rows
promiseArray
是undefined
。 我错过了什么?
$("#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; }
承诺不是一个神奇的物体,当它被解决时“变成”一个不同的价值。 当你在做rows.push(promiseArray[i]);
,你收集的是承诺对象,而不是它们所包含的结果。
要访问承诺已经或将要履行的结果,您需要将.then(…)
回调链接到它,您可以在其中访问结果作为参数。 要从数组中的所有promises中收集结果,可以使用Promise.all
,它返回另一个promise,它不仅等待所有输入promise,还满足其结果值数组。
$("#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; }
您可以在then
处理程序中收到promise的结果:
Promise.all(promiseArray).then( function (results) { // Wait for all promises to resolve var rows = [headers].concat(results); exportToCsv( fileName, rows ); })
- 在jQuery中,有没有办法只绑定一次点击?
- jstree delete_node()未删除
- jQuery Validate,Select2和Bootstrap 3 Popovers – 如何将Popover绑定到Select2的父元素而不是隐藏的选择元素
- Jquery ajax表单数组提交
- 使用javascript自动检测并从输入中删除http://
- jQuery Mobile:更新导航栏时替代.trigger(’create’)或.page()?
- Javascript / jQuery – 以英尺和英寸显示英寸
- 如何在同一页面上为多个div制作jQuery slidetoggle效果?
- jQuery函数在新窗口中打开链接