首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待多个异步函数在javascript中完成

等待多个异步函数在javascript中完成
EN

Stack Overflow用户
提问于 2022-01-28 22:01:40
回答 2查看 1K关注 0票数 1

我想向服务器发出一系列ajax请求,然后使用我以前收到的数据进行最后的ajax请求。显然,在完成最后的请求之前,我需要等待前面的请求完成。我很难用javascript实现这一点。

我不想压垮服务器,所以理想情况下,所有请求都是按顺序完成的。

我的简单测试代码如下(用睡眠替换web请求):

代码语言:javascript
复制
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

var urls = ['1', '2', '3'];

const slowFunc = () => {

    urls.forEach(async (url) => {

        //Don't change this section!
        console.log("a"+url);
        await sleep(5000);
        console.log("b"+url); //I want this to run before c
    });

};

slowFunc();
console.log("c");

这个打印"c“之前,睡眠是完成,这是错误的。如何使输出如下所示?

代码语言:javascript
复制
a1
b1
a2
b2
a3
b3
c

出于兴趣,我怎么得到这个输出?(a和b段中的确切顺序并不重要。)

代码语言:javascript
复制
a1
a2
a3
b1
b2
b3
c

我试着读ES2018:异步迭代,但这让我大吃一惊。

Update:我很快重新考虑了我的示例,所以这里有一个更好的示例(仍然不起作用):

代码语言:javascript
复制
var urls = ['https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.2.0/purify.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.8.3/system.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.18.6/slimselect.min.js'];
var results = {};

const webRequest = (url) => {
    $.ajax({
        type: "GET",
        url: url,
    }).then(data => {
        results[url] = data;
        console.log("b"+url+","+results[url]); //I want this to run before c
    });
}

const slowFunc = () => {

    urls.forEach((url) => {
        console.log("a"+url);
        webRequest(url);
    });

};

slowFunc();
console.log("c");

到目前为止,谢谢您的评论。

Update 2:基于Antonio Della Fortuna的建议解决web请求问题:

代码语言:javascript
复制
var urls = ['https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.2.0/purify.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.8.3/system.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.18.6/slimselect.min.js'];
var results = {};

const webRequest = (url) => {
    return new Promise((resolve, reject) => {

        $.ajax({
            type: "GET",
            url: url,
            error: function (data, status, er) { 
                console.log("b,"+url+",failed");
                resolve(); 
            },
        }).then(data => {
            results[url] = data;
            console.log("b,"+url+","+results[url]); //I want this to run before c
            resolve();
        });
    });
}

const slowFunc = async () => {

    for (let i = 0; i < urls.length; i++)
    {
        var url = urls[i];
        console.log("a,"+url);
        await webRequest(url);
    };

};

slowFunc().then(() => {
    console.log("c");
    console.log(results);
})
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-28 22:34:14

有两种方法取决于您的用例,您可以在这里找到工作示例-> https://codesandbox.io/s/zen-carson-ksgzf?file=/src/index.js:569-624

  1. 并行解决方案:您可以并行运行函数中的请求,然后按如下方式打印"c"
代码语言:javascript
复制
    const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

    var urls = ["1", "2", "3"];
    
    const slowFunc = async () => {
      await Promise.all(
        urls.map(async (url) => {
          //Don't change this section!
          console.log("a" + url);
          await sleep(5000);
          console.log("b" + url); //I want this to run before c
        })
      );
    };
    
    slowFunc().then(() => {
      console.log("c");
    });
  1. 同步解决方案:您可以像运行同步请求一样运行所有请求,并按顺序等待:
代码语言:javascript
复制
    const slowFuncSeq = async () => {
      for (const url of urls) {
        //Don't change this section!
        console.log("a" + url);
        await sleep(5000);
        console.log("b" + url); //I want this to run before c
      }
    };

    slowFuncSeq().then(() => {
      console.log("c");
    })
票数 2
EN

Stack Overflow用户

发布于 2022-01-28 22:16:00

在迭代过程中执行异步操作并不像您可能期望的那样工作。

当您执行forEach时,每个元素将被同步迭代。因此,每个元素将被迭代并调用回调函数,这就是为什么您首先看到每个元素的“a”日志。

这方面的例外是使用for...of循环,但对于其他迭代器,等待只会在回调函数中阻塞。

如果试图将请求的数量限制在API上,则可以实现漏桶算法。或者,您可以使用延迟函数将迭代重构为for...of循环,以阻止那些维护顺序但不太理想的请求,因为请求的速度将是延迟时间加上完成其他异步任务的时间。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70900765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档