方式二

代码

async backDish(list) {
  this.loading = true;

  let dateNow = await this.$api.custom.formatChange(new Date(), 'YYYY-MM-DD HH:mm:ss');
  let newList = [];
  let promises = list.map(async (item) => {
    try {
      let {
        data
      } = await this.$api.Canteen.getDishesStockCommon({
        id: item.id,
        startTime: item.lastTime,
        endTime: dateNow
      });

      delete data.sysDishesStockDetails;
      return {
        id: item.id,
        newDisheName: item.newDisheName,
        opType: this.row.type,
        pdqNum: item.stockNum,
        pdhNum: this.row.type === '03' ? 0 : undefined,
        sellSum: data.sellSum,
        lastTime: item.lastTime,
        zfSum: data.zfSum,
        remark: ''
      };
    } catch (e) {
      this.$message.error('数据加载失败!', e);
    } finally {
      this.loading = false;
    }
  });

  newList = await Promise.all(promises);
  this.tableList = [...newList, ...this.tableList];
  this.loading = false;
}

解析

主要功能
加载状态管理:开始设置loading=true,结束时设为false
获取当前时间:格式化为YYYY-MM-DD HH:mm:ss
并发请求处理:对每个菜品并发请求库存数据
数据处理:提取需要的数据字段,构建新对象
合并数据:将新数据合并到现有表格数据前部


关键点说明
Promise.all用于等待所有并发请求完成
map+async/await实现并发异步请求
操作类型(opType)为’03’时,pdhNum设为0,否则undefined
错误时会显示提示但继续执行(可能留下undefined值)
finally中的loading=false会导致过早结束加载状态(建议移除)


执行流程
开启加载状态
获取并格式化当前时间
对每个菜品发起库存查询请求
处理返回数据,构建新数据结构
等待所有请求完成
合并新旧数据
关闭加载状态


注意事项
错误处理不够完善,可能导致结果数组包含undefined
两个地方设置loading=false(建议只保留最后的设置)
并发请求若其中一个失败不影响其他请求执行


方式一

代码实现

async function circularRequest() {
    let urlList = [
        { id: 'id1', userId: 'userId9914', url: '/index' },
        { id: 'id2', userId: 'userId1386', url: '/type' },
        { id: 'id3', userId: 'userId1850', url: '/about' }
    ],
        arr = [];

    for (let i = 0; i < urlList.length; i++) {
        await getJurisdiction(urlList[i]).then((result) => {
            let { code, data } = result;

            if (code === 200) arr.push({ ...data });
        });
    }

    console.log("arr: ", arr);
    // arr: (3) [{…}, {…}, {…}]
}

// 模拟后端返回数据
function getJurisdiction(params) {
    return new Promise((resolve, reject) => {
        let data = {
            code: 200,
            message: "操作成功",
            data: null,
        };

        if (params.userId) {
            data.data = {
                id: `id${Math.floor(Math.random() * 10000) + 1}`,
                userId: params.userId,
                str: Math.random().toString().split(".")[1],
                value: Math.floor(Math.random() * 100000) + 1
            };

            return resolve(data);
        } else {
            data.code = 500;
            data.message = "操作失败";
            data.data = null;

            return reject(data);
        }
    });
}

circularRequest();

解析

使用Promisethen方法配合async/await的方式实现。一般情况下请求接口都会使用到Promise,所以使用await来截获then使for循环能保持等待的效果。


split

w3school

split()方法将字符串拆分为子字符串数组。
split()方法返回新数组,不会更改原始字符串。
如果(" ")用作分隔符,则字符串在单词之间进行拆分。


MDN String.prototype.split()

split()方法接受一个模式,通过搜索模式将字符串分割成一个有序的子串列表,将这些子串放入一个数组,并返回该数组。


MDN Array.prototype.splice()

splice()方法通过移除或者替换已存在的元素和/或添加新元素就地改变一个数组的内容。
要创建一个删除和/或替换部分内容而不改变原数组的新数组,请使用toSpliced()。要访问数组的一部分而不修改它,参见slice()


toString

w3school

toString()方法将对象作为字符串返回。
如果toString()方法不能返回字符串,则返回"[object Object]"
Object.toString()总是返回对象构造函数。
toString()方法不会更改原始对象。
每个JavaScript对象都有toString()方法。
当需要将对象显示为文本(如在HTML中)或需要将对象用作字符串时,JavaScript在内部使用toString()方法。
通常,您不会在自己的代码中使用它。


MDN

toString()方法返回一个表示该对象的字符串。该方法旨在重写(自定义)派生类对象的类型转换的逻辑。


random

MDN

Math.random()函数返回一个浮点数,伪随机数在范围从0到小于1,也就是说,从0(包括0)往上,但是不包括1(排除1),然后您可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。


w3school

random()方法返回从0(含)到1(不含)的随机数。


floor

MDN

Math.floor()函数总是返回小于等于一个给定数字的最大整数。


w3school

floor()方法将数字向下舍入为最接近的整数,并返回结果。
如果传递的参数是整数,则不会舍入该值。
floor()方法执行的是向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数。


Math

MDN

Math是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math不是一个函数对象。
Math用于Number类型。它不支持BigInt
与其他全局对象不同的是,Math不是一个构造器。Math的所有属性与方法都是静态的。引用圆周率的写法是Math.PI,调用正余弦函数的写法是Math.sin(x)x是要传入的参数。Math的常量是使用JavaScript中的全精度浮点数来定义的。


w3school

Math对象允许执行数学任务。
Math不是构造函数。Math的所有属性/方法都可以通过使用Math作为对象来调用,而无需创建它。


reject

MDN

Promise.reject()静态方法返回一个已拒绝(rejected)的Promise对象,拒绝原因为给定的参数。


resolve

MDN

Promise.resolve(value)方法返回一个以给定值解析后的Promise对象。如果这个值是一个promise,那么将返回这个promise;如果这个值是thenable(即带有then方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。
不要在解析为自身的thenable上调用Promise.resolve。这将导致无限递归,因为它试图展平无限嵌套的promise。一个例子是将它与Angular中的异步管道一起使用。在此处了解更多信息。


Promise

MDN

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果值。
一个Promise对象代表一个在这个promise被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值。异步方法并不会立即返回最终的值,而是会返回一个promise,以便在未来某个时候把值交给使用者。
一个Promise必然处于以下几种状态之一
待定(pending):初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled):意味着操作成功完成。
已拒绝(rejected):意味着操作失败。
待定状态的Promise对象要么会通过一个值被兑现,要么会通过一个原因(错误)被拒绝。当这些情况之一发生时,我们用promisethen方法排列起来的相关处理程序就会被调用。如果promise在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。
因为Promise.prototype.thenPromise.prototype.catch方法返回的是promise,所以它们可以被链式调用。


then

MDN

then()方法返回一个Promise (en-US)。它最多需要有两个参数,Promise的成功和失败情况的回调函数。


await

MDN

await操作符用于等待一个Promise兑现并获取它兑现之后的值。它只能在异步函数或者模块顶层中使用。


async

w3school

函数前的关键字async使函数返回promise


MDN

async函数是使用async关键字声明的函数。async函数是AsyncFunction构造函数的实例,并且其中允许使用await关键字。asyncawait关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise
async函数还可以被作为表达式来定义。

Logo

一站式 AI 云服务平台

更多推荐