koa 异步返回ctx.body eslint 报错 require-atomic-updates

module.exports = async (ctx) => {

const reqUrl = ctx.request.header.referer;
const urlParam = url2param(reqUrl);
const offset = (urlParam.page - 1) * urlParam.pageSize;
try {
// 获取数据库数据
    const data = await User.findAndCountAll({
        attributes: [
            'username',
            'realname',
            'phone',
            'roleType',
            'hasActive',
            'createdAt'
        ],
        offset,
        limit: +urlParam.pageSize
    });
    // 将数据返回给前端
    ctx.body = {data};    //eslint报错  require-atomic-updates
} catch (e) {
    ctx.body = {...e};    //eslint报错  require-atomic-updates
}

};

前端返回数据无误,但是
eslint报错信息:
Possible race condition: ctx.body might be reassigned based on an outdated value of ctx.body.

没弄明白为什么,不知问题出在哪.

阅读 10.8k
4 个回答

正好我也遇到这个问题了。其实官方文档的例子也是说明了问题:

let totalLength = 0;

async function addLengthOfSinglePage(pageNum) {
  totalLength += await getPageLength(pageNum);
}

Promise.all([addLengthOfSinglePage(1), addLengthOfSinglePage(2)]).then(() => {
  console.log('The combined length of both pages is', totalLength);
});

这里面有多个异步操作同时进行,而顺序是不确定的,totalLength的值可能会发生不准确的赋值改变,导致结果不正确,后面也有提供解决办法。


我简单总结下,如果有多个异步方法,赋值给同一个变量,那这里面存在很多不确定性,可能发生错误。

而你的例子中只有一个await进行查询,其实是可以忽略这个错误的。直接在eslintrc配置中的rule添加"require-atomic-updates": "off",来关闭提示。

还是提醒一下:

let result;
async function foo() {
  result += await somethingElse;

  result = result + await somethingElse;

  result = result + doSomething(await somethingElse);
}

这种就一定要小心了!

新手上路,请多包涵

这个我看了,把你的 await 去掉,改成同步代码,就OK了,至于为什么,就是第一个答案,给的链接的意思。如果你一定要用
await ,那你再找别的办法。eslint 只是把这么输出的风险告诉你。希望可以帮助到后来的查这个问题的人。

我也遇到这问题了。感觉是eslint的判断依据出问题了。eslint的出发点是好的,但是把一些正常情况也当成有问题来对待了,对于这些还没有完善的规则,建议关闭。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题