JavaScript等待所有异步调用完成 [英] JavaScript Wait until all async calls finish

查看:100
本文介绍了JavaScript等待所有异步调用完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些帮助来处理JavaScript中的异步调用。我有一个for循环,每个循环调用一个异步HttpRequest,并将其响应添加到一个数组。我希望程序等到所有异步调用完成后再继续jQuery(仅用于DOM操作)。我已经搜索了很多解决方案但没有真正有用,没有大量更改我的代码或依赖jQuery。

I need some help with handling async calls in JavaScript. I have a for loop, each loop calls an async HttpRequest, and adds its response to an array. I want the program to wait until all the async calls are finished before proceeding without jQuery (which is only used for DOM manipulation). I've searched quite bit for solutions but none really worked without heavily changing my code or relying on jQuery.

function httpGet(theUrl, callback) {
    var xmlRequest = new XMLHttpRequest();
    xmlRequest.onreadystatechange = function() {
        if (xmlRequest.readyState == 4 && xmlRequest.status == 200) {
            callback(xmlRequest.responseText);
        }
    }
    xmlRequest.open("GET", theUrl, true);
    xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlRequest.setRequestHeader("Accept", "application/json");
    xmlRequest.send(null);
}
$(document).ready(function() {    
    var channels = ["freecodecamp", "storbeck", "terakilobyte", "habathcx","RobotCaleb","thomasballinger","noobs2ninjas","beohoff"];
    var urls = channels.map((x) => "https://api.twitch.tv/kraken/channels/" + x);
    var data = [];
    (function(urls, data) {
        urls.forEach(function(url) {  
            function(resolve, reject) {
                httpGet(url, function(response) {
                    data.push(JSON.parse(response));
                })
            };
        })
    })(urls, data);

    // Continue after all async calls are finished
})

更新:使用Promise编辑,但仍然无法正常工作,也许我做错了。

UPDATED: Edited with Promise, but still not working, maybe I did something wrong.

function httpGet(theUrl, callback) {
    return new Promise(function(resolve, reject) {
        var xmlRequest = new XMLHttpRequest();
        xmlRequest.onreadystatechange = function() {
            if (xmlRequest.readyState == 4 && xmlRequest.status == 200) {
                callback(xmlRequest.responseText);
            }
        }
        xmlRequest.open("GET", theUrl, true);
        xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlRequest.setRequestHeader("Accept", "application/json");
        xmlRequest.send(null);
    })
}
$(document).ready(function() {    
    var channels = ["freecodecamp", "storbeck", "terakilobyte", "habathcx","RobotCaleb","thomasballinger","noobs2ninjas","beohoff"];
    var urls = channels.map((x) => "https://api.twitch.tv/kraken/channels/" + x);
    var data = [];
    var promises = [];
    (function(urls, data) {
        urls.forEach(function(url) {  
            var promise = httpGet(url, function(response) {
                data.push(JSON.parse(response));
            });
            promises.push(promise);
        })

        Promise.all(promises).then(function() {
            console.log(data);
        })
    })(urls, data);
})


推荐答案

使用promise,您不应使用 callback 参数。改为从承诺中调用 resolve / 拒绝函数。

With promises, you should not use a callback parameter. Call the resolve/reject functions from the promise instead.

不是将回调传递给调用,而是在 .then 处理程序中使用promise的结果链接你要做的事情。

Instead of passing a callback to the call, chain the things you want to do with the result of the promise in a .then handler.

function httpGet(theUrl) {
    return new Promise(function(resolve, reject) {
        var xmlRequest = new XMLHttpRequest();
        xmlRequest.onreadystatechange = function() {
            if (xmlRequest.readyState == 4) {
                if (xmlRequest.status == 200) 
                    resolve(xmlRequest.responseText);
    //              ^^^^^^^
                else
                    reject(new Error(xmlRequest.statusText)); // or something
            }
        }
        xmlRequest.open("GET", theUrl, true);
        xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlRequest.setRequestHeader("Accept", "application/json");
        xmlRequest.send(null);
    });
}
$(document).ready(function() {    
    var channels = ["freecodecamp", "storbeck", "terakilobyte", "habathcx","RobotCaleb","thomasballinger","noobs2ninjas","beohoff"];
    var urls = channels.map((x) => "https://api.twitch.tv/kraken/channels/" + x);
    var promises = urls.map(function(url) {
//                      ^^^ simpler than forEach+push
        var promise = httpGet(url); // <-- no callback
        return promise.then(JSON.parse);
    });

    Promise.all(promises).then(function(data) {
//                                      ^^^^
        console.log(data);
    });
})

这篇关于JavaScript等待所有异步调用完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆