为什么我的承诺没有返回任何价值?

时间:2017-03-16 01:22:40

标签: javascript jquery promise q

在这个稍微减少的代码中,一周一次从API下载一周或多周的观察结果,并汇总到rows并导出为CSV。至少这是个主意。实际发生的情况是Uncaught (in promise) TypeError: Cannot read property 'toString' of undefined在(未显示)exportToCsv函数中出现,因为从_promise推送到promiseArray的{​​{1}}即将出现rows。我错过了什么?

undefined

2 个答案:

答案 0 :(得分:2)

承诺不是一个神奇的物体,当它被解决时“变成”一个不同的值。当您执行rows.push(promiseArray[i]);时,您收集的是承诺对象,而不是它们包含的结果。

要访问承诺已经或将要履行的结果,您需要将.then(…)回调链接到它,您可以在其中访问结果作为参数。要从数组中的所有promise中收集结果,可以使用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;
}

答案 1 :(得分:1)

您可以在then处理程序中收到您的承诺结果:

Promise.all(promiseArray).then( function (results) { // Wait for all promises to resolve
    var rows = [headers].concat(results);
    exportToCsv( fileName, rows );
  })