前端JS for循环内异步接口变成同步提交(JavaScript for循环异步变同步)

遇见的问题:
导入Excel文件的时候,将每行数据整合成一个数组,循环数组插入每一条数据,插入数据后要判断是否插入成功,如果没插入成功的话,停止循环,不再插入后面的数据。甚至插入数据后,还要进行一些其他操作。

解决方法: 使用 Promiseasync/await 即可。

重点: JS的循环有部分不支持异步变同步
支持: for()循环for in , for of , while(), promise.all()
不支持: forEach(), map()

下面直接上代码了

代码:


var data_arr = [
    {
        name: "姓名一",
        sex: "男"
    },
    {
        name: "姓名二",
        sex: "女"
    },
    {
        name: "姓名三",
        sex: "男"
    }
]
async function arrInsert() {
    for (let i = 0; i < data_arr.length; i++) {
        let result_data = await createUser(data_arr[i]);
        if (!result_data.result) {
            // 如果出错,就跳出循环
            this.$message({
                message: `${i + 1} 行数据 ${data_arr[i].name}(${data_arr[i].sex}),插入失败`,
                type: 'error'
            });
            break;
        }
    }
}

// 添加用户信息接口
async function createUser(data) {
    return await new Promise(function (resolve, reject) {
        // 处理异步逻辑时候调用resolve和reject函数
        axios({
            method: 'POST',
            url: `${base_url}/api/h5/invitation/add`,
            headers: {
                // 没有可以不要token
                // authorization: `bearer ${token}`
            },
            // 数据
            data: data
        }).then(res => {
            let resp = res.data;
            if (resp.code == 1) {
                if (resp.data.code == 200) {
                    resolve({
                        "result": true
                    });
                }
            } else {
                resolve({
                    "result": false,
                    "msg": resp.msg
                });
            }
        }).catch(req => {
            reject({
                "result": false,
                "msg": ""
            });
        });
    });
}

注意: 如果有用到 setTimeout 的时候,将 setTimeout 放在 Promise 里面,例如:

// 添加用户信息接口
// 添加用户信息接口
async function createUser(data) {
    return await new Promise(function (resolve, reject) {
        // 延迟一秒执行
        setTimeout(() => {
            // 处理异步逻辑时候调用resolve和reject函数
            axios({
                method: 'POST',
                url: `${base_url}/api/h5/invitation/add`,
                headers: {
                    // 没有可以不要token
                    // authorization: `bearer ${token}`
                },
                // 数据
                data: data
            }).then(res => {
                let resp = res.data;
                if (resp.code == 1) {
                    if (resp.data.code == 200) {
                        resolve({
                            "result": true
                        });
                    }
                } else {
                    resolve({
                        "result": false,
                        "msg": resp.msg
                    });
                }
            }).catch(req => {
                reject({
                    "result": false,
                    "msg": ""
                });
            });
        }, 1000)
    });
}

补充个知识点:

支持异步变同步的循环: for()循环for in , for of , while(), promise.all()
可以使用 break 跳出当前循环,循环后面的代码仍然可以执行。
可以使用 return 可以终止当前函数,循环后面的代码不可以执行。
可以使用 continue 跳过当次循环,仍然执行后续的循环。

不支持异步变同步的循环: forEach(), map()
无法使用 breakcontinue来跳出遍历。
通过抛出异常 throw Error() 的方式跳出循环,实现 break 效果。
通过 return 跳过当次循环,实现 continue 的效果。
例如:

var arr = [1, 2, 3, 4, 5, 6, 7, 8];
var id = 5;
try {
    arr.forEach(function (item, index, arr) {
        if (item === 1) return;
        console.log(item)
        if (item === id) {
            //满足条件,跳出循环
            throw Error();
        }
    })
} catch (e) {
}

前端JS for循环内异步接口变成同步提交(JavaScript for循环异步变同步)_第1张图片

你可能感兴趣的:(web前端,前端,javascript,java)