如何解决循环中的http请求的异步问题

    let paramArr = JSON.parse(paramArray)
    let data = [];
    paramArr.forEach(async (val, i) => {
      let easywlb = dasign ? tqyybm : (tqyybm.substr(0, 2) === '02' ? ('12' + tqyybm.substr(2, 4)) : ('11' + tqyybm.substr(2, 4)));
      let param = { '这是一些参数' };
      await this.post('这是接口', param);
      let result = this.get('data');
      
      for (let item in result) {
        data.push({ 'a': result[item].a, 'b': result[item].b });
      }
    })
    //因为异步现在的data是[]
    ctx.body = { data, success: this.success() }
    

如何解决此过程中多次循环异步操作带来的问题
麻烦详细说下 谢谢

阅读 4.7k
4 个回答
const paramArr = JSON.parse(paramArray).map(async(val)=>{
    let easywlb = dasign ? tqyybm : (tqyybm.substr(0, 2) === '02' ? ('12' + tqyybm.substr(2, 4)) : ('11' + tqyybm.substr(2, 4)));
    let param = { '这是一些参数' };
    await this.post('这是接口', param);
    let result = this.get('data');
    
    const map = [];
    for (let item in result) {
      map.push({ 'a': result[item].a, 'b': result[item].b });
    }
    return map;
});

const data = await Promise.all(paramArr);

forEach不适合接收这种回调函数。
async函数返回的是Promise,所以你可以用map得到一个Promise的数组。 你可以promises= paramArr.map(async (val, i) => ...
然后使用await Promise.all(promises)


我再看了下你的代码,data.push({ 'a': result[item].a, 'b': result[item].b });在这里的顺序是不确定的,这样的话data的顺序就会有问题了,你或者可以使用for循环放弃并发请求,或者可以最后对data进行排序获得和原来一样的顺序(每次push的时候同时存入索引i,用来排序)。


当然如果data.push不立即处理,而是让Promise返回结果,那么Promise.all就是有序的,然后再存放到data里。

const { EventEmitter } = require('events');

var event = new EventEmitter();

let paramArr = JSON.parse(paramArray);
let data = [];
paramArr.forEach(async (val, i) => {
    let easywlb = dasign
        ? tqyybm
        : tqyybm.substr(0, 2) === '02'
            ? '12' + tqyybm.substr(2, 4)
            : '11' + tqyybm.substr(2, 4);
    let param = {
        /* '这是一些参数' */
    };
    await this.post('这是接口', param);
    let result = this.get('data');
    for (let item in result) {
        data.push({ a: result[item].a, b: result[item].b });
    }
    event.emit('loaded');
});
//因为异步现在的data是[]
var count = 0;
event.on('loaded', function() {
    if (++count === paramArr.length) {
        event.emit('finish');
    }
});

event.on('finish', function() {
    ctx.body = { data, success: this.success() };
})

事件监听风格的

不要用forEach,直接for循环就行,也没必要呀asnyc/await,既然this.post方法是promise,就直接promise调用就行

let paramArr = JSON.parse(paramArray)
let data = [];
let promiseArr = paramArr.map(val=>{
    let easywlb = dasign ? tqyybm : (tqyybm.substr(0, 2) === '02' ? ('12' + tqyybm.substr(2, 4)) : ('11' + tqyybm.substr(2, 4)));
    let param = { '这是一些参数' };
    return this.post('这是接口', param).then(()=>{
        let result = this.get('data');
        return result.map(n=>return {a:n.a, b:n.b}))
    })
});
promise.all(promiseArr)
    .then((resultArr)=>ctx.body = { data: data.reduce((p,c)=>[p.concat(c), p][1],[]), success: this.success() })
    .catch(err=>console.log(err))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题