await is a reserved word,yield is a reserved word报错解决

解决await与yield报错
本文解析了在React应用中遇到的awaitisareservedword与yieldisareservedword错误,阐述了await与yield关键字的正确使用场景,并通过实例展示了如何在异步函数与generator函数中避免此类错误。

await is a reserved word报错

  该报错提示,await 是保留字 ,一开始由于使用的框架是 react ,某个接口需要在 state 更新后,再进行调用,情况类似如下代码(为了演示故意写成如下情况)。

import { Restful } from './Restful'
...

/**
 * @private
 * @method 查询使用接口数据
 * @param {object} data
 * @returns undefined
 * @author
 */
onDataChange = (data) => {
   this.setState({
        data
    }, () => {  // 该方法需要先把数据更新到state中,然后再从state中获取数据进行查询
        let dataID = null;
        //查询接口数据
        let queryData = {
            method: 'POST',
            url: '/restful/query/data',
            data: {
                code: this.state.data.code,
                data: this.state.data.param
            }
        };
        Restful.fetch(queryData).then((response) => {  //先查询这个接口,获取ID
            if (response.data.code === 0) {
                dataID = response.data.dataID;
            }
        });

        //使用接口数据
        let useData = {
            method: 'POST',
            url: '/restful/use/data',
            data: {
                id: dataID
            }
        };
        Restful.fetch(useData).then((response) => {   //用上面查询到的ID,再调用这个接口
            if (response.data.code === 0) {
                ...
            }
        });
    });
}

  上面的 restful 是封装的 axios 接口,类似下方代码。

export default class Restful {
    /**
     * 外部调用发送请求
     * @param {object} fetchObj 请求时传入参数
     */
    static fetch(fetchObj) {
        return new Promise(function (resolve, reject) {
            axios({
                ...fetchObj,
                timeout: 30000,
                headers: {
                    Authorization: window['token'],
                    'Content-Type': 'application/json'
                }
            }).then(function (response) {
                resolve(response);
            }).catch(function (response) {
                reject(response);
            });
        });
    }
}

  上面方法中,我想先执行 queryData ,查询到 id 后,在拿着 id 去调用下一个接口,一开始直接在最外层的方法上增加了 async 如下所示。

onDataChange = (data) => {
    async function changeData(data) {    
        this.setState({
            data
        }, () => {    // ** 此处是需要修改的点
            let dataID = null;
            //查询接口数据
            let queryData = {
                ...
                }
            };
            await Restful.fetch(queryData).then((response) => {  //这里直接报错await is a reserved word
                if (response.data.code === 0) {
                    dataID = response.data.dataID;
                }
            });

            //使用接口数据
            let useData = {
                ...
            };
            await Restful.fetch(useData).then((response) => {
                if (response.data.code === 0) {
                    ...
                }
            });
        });
    }
    changeData(data);
}

  上面代码运行直接报错 await is a reserved word 原因在上面 ** 符号处,原因是 await 只能在 async 函数 中使用(这句话很重要)。

  上面存在函数嵌套,虽然外层函数设置成了 async 函数 但是其内部存在一个回调函数,严格意义上来说,这个回调函数,不属于 async function changeData 的内部,所以该回调函数没有设置成 async,那么其内部的 await就不会生效,而是当做变量去处理,同时这个又是关键字,才报出来那个错。

  修改方法很简单,把外面的那个 async 放到回调函数前面就可以了,效果如下

onDataChange = (data) => {
                       // 原来在这里的 async 删掉
    this.setState({
        data
    }, async function() {    // 把这个回调函数设置成 async函数
        let dataID = null;
        //查询接口数据
        let queryData = {
           ...
        };
        await restful.fetch(queryData).then((response) => {
            if (response.data.code === 0) {
                dataID = response.data.dataID;
            }
        });

        //使用接口数据
        let useData = {
           ...
        };
        await restful.fetch(useData).then((response) => {
            if (response.data.code === 0) {
                ...
            }
        });
    });
}

  需要注意的是,如果 async 函数 内部没有 await 那么它和普通函数一样。

举一反三

  上面代码中,我故意加入了 restful 封装接口的使用,是应为它也符合回调函数设置成 async 的情况。举个例子,我想先查询第一个接口,然后第二个,然后第三个。

async function query() {    // 如果 async 写在这里,await那里还是会报错
    Restful.fetch(first).then((response) => {

        await Restful.fetch(second).then((response) => {
        
        });

        await Restful.fetch(third).then((response) => {
            
        });
    })
}

正确写法

Restful.fetch(first).then(async function(response) {  //写在这里才可以正常运行

     await Restful.fetch(second).then((response) => {
     
     });

     await Restful.fetch(third).then((response) => {
         
     });
 })

yield is a reserved word报错

  yield is a reserved word 报错原因和上面 await 一样,yield 必须写在 generator 函数 内部,回调函数不属于某个函数,而是属于在满足某些条件后,执行的函数。写法如下

Restful.fetch(first).then((response) => {

     Restful.fetch(second).then((response) => {
     	let useData = generator();  //在第二个异步调用中使用 generator 函数
     	useData.next();
     	useData.next();
     });
     fucntion* generator() {   //把第三个要执行的异步设置成 generator 函数
		yield Restful.fetch(third).then((response) => {
         
     	});
	 }
})

  个人感觉,generator 函数 的作用在于,可以手动的操作函数运行,让谁执行,让谁停止,变成了完全可控状态,不过相比于async 使用起来还是相对麻烦一点。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值