11月10, 2021

如何正确的在JS循环中使用异步?

如何正确的在JS循环中使用异步?

周末在用react-redux做B站课程列表的时候,遇到了一个在循环中使用异步的问题,记录一下.

问题的场景是这样的,我做了一个课程列表的Tab选项卡效果.(基于React+React-redux)创建.后端接口也是自己用nodejs+koa2创建的.

我想实现的效果是统计每个课程分类下面课程的总数.

前端页面截图

如上图所示,我想在接口中统计每个分类下面课程总数,然后返回一个totalCount字段合并上去.

首先,我需要循环/course/get_course_fields这个接口返回的数据,然后拿到每项的fieldType字段,然后循环异步调用/course/get_field_course_list这个接口,统计每个课程分类对应的条数.添加到接口字段中返回数据.

原因分析:

因为async函数执行完会返回Promise对象,map就直接接收后装进新数组了,数组内容直接变成了四个Promise,这显然不是我们想要的结果,所以我们要对Promise数组再进一步操作取出其中的值。

后端打印截图

controller控制器中的相关代码:

// 合并数据方法


const courseModel = require("../lib/mysql.js");

const fdata = async (data) => {
const promises = data.map(async item => {
const listItem = await courseModel.get_field_course_list(item.fieldType).then(res => res.length);
    return listItem;
  });

  const listItems = await Promise.all(promises);
  console.log('promises', promises);
  console.log('result listItems', listItems);
  const res = data.map((item, index) => ({
    ...item,
    totalCount: listItems[index]
  }));
  return res;
}

// 查询分类数据

exports.getFieldCourse = async ctx => {
  await courseModel
    .get_field_course()
    .then(async result => {
      ctx.body = {
        code: 0,
        message: "成功",
        result: await fdata(result)
        // result:result
      };
    })
    .catch(() => {
      ctx.body = {
        code: 1,
        message: "失败"
      };
    });
}

这里的Promise.all会将一个由Promise组成的数组依次执行,并返回一个Promise对象,该对象的结果为数组产生的结果集。

并且下面一个接口查询分类的数据,要使用await关键字,对result数据进行合并处理返回即可.

{
    result:await fdata(result)
}

另外附上项目Github地址:

更多请参考:

https://github.com/pybyongbo/antd-react-demo

https://github.com/pybyongbo/jsplusplusApi

本文链接:https://901web.com/post/js-map-async-await.html

-- EOF --

Comments

请在后台配置评论类型和相关的值。