Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

javascript - How do I refactor to wait for the AJAX queries to finish before exporting to CSV?

I have the code below triggered by button click. When I run it, the CSV is created but is empty. The console.log(rows) output is as expected, but has a note saying Value below was evaluated just now.

How do I make the execution of exportToCsv wait until the AJAX calls are complete?

$("#downloadBtn").click(function() {
    weeks = getWeeks(startDate.val(), endDate.val());
    // start downloading the data
    for (i=0; i< weeks.length; i++) {
        // contains $.ajax query that appends to "rows"
        fetchDataWeek( weeks[i][0], weeks[i][1] );  
    }
    console.log(rows);
    exportToCsv( fileName, rows );            
});

Edit in response to surajck's answer:

In addition to the suggested code using Promises, I've edited my fetchDataWeek function as follows, but when I run it I get Uncaught TypeError: Promise resolver undefined is not a function.

function fetchDataWeek( startDay, endDay ) {
    startDay = makeDateString(startDay);
    endDay = makeDateString(endDay);
    url = "https://api" + startDay + endDay + ".json";
    $.ajax({
        url: url,
        success: function(result){
            parseHistory(result);
            _promise.resolve(result);
        }
    });            
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is some generic code to help you understand:

$("#downloadBtn").click(function() {
    weeks = getWeeks(startDate.val(), endDate.val());
    // start downloading the data

    // Create an array to hold all your promises
    var promiseArray = [];

    for (i=0; i< weeks.length; i++) {
        // contains $.ajax query that appends to "rows"
        var _promise = Q.defer(); // Create a promise (using https://github.com/kriskowal/q)

        // send this promise to the ajax callback
        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
        console.log(rows);
        exportToCsv( fileName, rows );
    })            
});

Your fetchDataWeek code then becomes:

function fetchDataWeek( startDay, endDay, _promise ) {
    startDay = makeDateString(startDay);
    endDay = makeDateString(endDay);
    url = "https://api" + startDay + endDay + ".json";
    $.ajax({
        url: url,
        success: function(result){
            parseHistory(result);
            _promise.resolve(result); // resolving that promise here
        },
        error: function (error) {
            _promise.reject(error) // rejecting it in case of error
        }
    });            
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...