最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

在Axios中半同步执行异步操作

IT培训 admin 2浏览 0评论

在Axios中半同步执行异步操作

我有以下代码:

   * Fetch stats from api
   */
  fetchStats() {
    this._isFetching = true;
    // fetch stats after building url and replacing invalid characters
    return new Promise(async (resolve, reject) => {
      await API.fetchStats(this.rsn)
        .then(jres => {
          this.skills = jres.main.skills;
          this._isFetching = false;
          resolve('success');
        })
        .catch(err => {
          console.log(err);
          console.log('error retreiving stats');
          this._isFetching = false;
          reject('Failed to retreive stats');
        })
        .finally(() => {
          this._isFetching = false;
        });
    });
  }

我以为使其与await异步将使其等待直到得到响应后再继续。我在测试中添加了返回诺言的功能,以查看是否可以使其同步。

然后是我的使用此方法的代码:

memberCollection.forEach(async el => {
        await el.player.fetchStats()
        .then(() => {
          console.log(`Refreshed ${el.player.rsn}'s account`);
        })
        .catch(console.log(`Failed to refresh ${el.player.rsn}'s account`));
});

我的想法是,它将等待直到收到响应,然后再刷新console.log,否则刷新成功或失败。相反,我看到的是一堆“成功”消息,后面是一串失败消息,表明它同时在foreach中运行then和catch消息。有谁知道我该怎么做。

我的问题是,Axios会不断超时(我的推测是,由于发送的请求数量众多,并且由于它从数据库中拉出,所以延迟了5-10秒),如果我导航到手动使用API​​ URL可以正常工作,就像我只做一个成员(而不是forEach一样)也可以。因此,我试图限制一次触发的请求数。我尝试将axios超时设置为10、20和60秒,但没有任何改善。

回答如下:

未链接到axios,但链接到async await

考虑

function slow(i){
    return new Promise((ok,ko)=>{
        return setTimeout(_=>ok(i), 1000)
    })
}
async function asyncForEach(arr, cb){
    for(var i = 0; i<arr.length; ++i){
        let el = arr[i];
        let res = await cb(el);
        console.log('async', res, new Date)
    }
}

/*
#foreach does not wait, but async and reduce are spaced by one second
foreach 4 2019-10-14T13:43:47.059Z
foreach 5 2019-10-14T13:43:47.071Z
foreach 6 2019-10-14T13:43:47.071Z
async 1 2019-10-14T13:43:47.071Z
async 2 2019-10-14T13:43:48.073Z
async 3 2019-10-14T13:43:49.074Z
reduce 7 2019-10-14T13:43:50.076Z
reduce 8 2019-10-14T13:43:51.078Z
reduce 9 2019-10-14T13:43:52.080Z
*/ 
async function main(){

    await [4,5,6].forEach(async el=>{
        let res = await slow(el);
        console.log('foreach', res, new Date)
    })
    await asyncForEach([1,2,3], slow);

    await [7,8,9].reduce((acc, el)=>acc.then(async _=>{
        let res = await slow(el);
        console.log('reduce', res, new Date);
        return;
    }), Promise.resolve())
}
main();

如从时间戳中所见,forEach不等待slow完成但是,asyncForEach在其迭代中does等待

您可能想要做的是

  • 编写与asyncForEach相同的for循环
  • 使用标准承诺(堆叠它们):
    [1,2,3].reduce((acc, el)=>acc.then(_=>{
        return slow(el);
    }), Promise.resolve())
    

在Axios中半同步执行异步操作

我有以下代码:

   * Fetch stats from api
   */
  fetchStats() {
    this._isFetching = true;
    // fetch stats after building url and replacing invalid characters
    return new Promise(async (resolve, reject) => {
      await API.fetchStats(this.rsn)
        .then(jres => {
          this.skills = jres.main.skills;
          this._isFetching = false;
          resolve('success');
        })
        .catch(err => {
          console.log(err);
          console.log('error retreiving stats');
          this._isFetching = false;
          reject('Failed to retreive stats');
        })
        .finally(() => {
          this._isFetching = false;
        });
    });
  }

我以为使其与await异步将使其等待直到得到响应后再继续。我在测试中添加了返回诺言的功能,以查看是否可以使其同步。

然后是我的使用此方法的代码:

memberCollection.forEach(async el => {
        await el.player.fetchStats()
        .then(() => {
          console.log(`Refreshed ${el.player.rsn}'s account`);
        })
        .catch(console.log(`Failed to refresh ${el.player.rsn}'s account`));
});

我的想法是,它将等待直到收到响应,然后再刷新console.log,否则刷新成功或失败。相反,我看到的是一堆“成功”消息,后面是一串失败消息,表明它同时在foreach中运行then和catch消息。有谁知道我该怎么做。

我的问题是,Axios会不断超时(我的推测是,由于发送的请求数量众多,并且由于它从数据库中拉出,所以延迟了5-10秒),如果我导航到手动使用API​​ URL可以正常工作,就像我只做一个成员(而不是forEach一样)也可以。因此,我试图限制一次触发的请求数。我尝试将axios超时设置为10、20和60秒,但没有任何改善。

回答如下:

未链接到axios,但链接到async await

考虑

function slow(i){
    return new Promise((ok,ko)=>{
        return setTimeout(_=>ok(i), 1000)
    })
}
async function asyncForEach(arr, cb){
    for(var i = 0; i<arr.length; ++i){
        let el = arr[i];
        let res = await cb(el);
        console.log('async', res, new Date)
    }
}

/*
#foreach does not wait, but async and reduce are spaced by one second
foreach 4 2019-10-14T13:43:47.059Z
foreach 5 2019-10-14T13:43:47.071Z
foreach 6 2019-10-14T13:43:47.071Z
async 1 2019-10-14T13:43:47.071Z
async 2 2019-10-14T13:43:48.073Z
async 3 2019-10-14T13:43:49.074Z
reduce 7 2019-10-14T13:43:50.076Z
reduce 8 2019-10-14T13:43:51.078Z
reduce 9 2019-10-14T13:43:52.080Z
*/ 
async function main(){

    await [4,5,6].forEach(async el=>{
        let res = await slow(el);
        console.log('foreach', res, new Date)
    })
    await asyncForEach([1,2,3], slow);

    await [7,8,9].reduce((acc, el)=>acc.then(async _=>{
        let res = await slow(el);
        console.log('reduce', res, new Date);
        return;
    }), Promise.resolve())
}
main();

如从时间戳中所见,forEach不等待slow完成但是,asyncForEach在其迭代中does等待

您可能想要做的是

  • 编写与asyncForEach相同的for循环
  • 使用标准承诺(堆叠它们):
    [1,2,3].reduce((acc, el)=>acc.then(_=>{
        return slow(el);
    }), Promise.resolve())
    

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论