await async - ESLint 中的竞争条件错误 require-atomic-updates
await async - race condition error in ESLint require-atomic-updates
下面的代码在使用 ESLint 检查时导致了竞争条件:
let match = false
try {
match = await something()
} catch (err) {
// do something
}
if (match === false) {
// do something
}
编写这段代码的更好方法是什么?
编辑:
let request = ctx.request.body || {}
let password = request.password
let match = false
try {
match = await bcrypt.compare(password, 'xxxxx')
} catch (err) {
ctx.throw(401, err)
}
if (match === false) {
ctx.throw(401, 'invalid password')
}
ctx.body = {
message: 'logged in ok'
}
ESLint 错误:
Possible race condition: ctx.body
might be reassigned based on an
outdated value of ctx.body
require-atomic-updates
您可以安全地忽略警告:)
ESLint 旨在捕捉这样的东西:
let value = 0;
async function race() {
value += await Promise.resolve(1);
console.log(value);
}
race(); race();
在这种情况下,race
在堆栈上记忆 value
,await
一个滴答,然后写回 value
。由于其他代码同时运行,value
可能已经更改,然后更新可能会关闭......它不是原子的。
然而,在您的情况下,您从 ctx.request.body
读取并写入 ctx.body
,因此没有非原子更新。此外,可能没有其他中间件同时访问同一个 ctx
,因此不会有任何并发修改。因此,在您的情况下,这是一个误报,甚至怀疑这在任何方面都是肯定的(它可能是 ESLint 中的错误)。
我意识到这个答案有点晚了,但对于遇到这个问题的任何未来用户来说,要禁用这个规则,在你的 .eslintrc.json
或你使用的任何相关配置中,只需指定:
"require-atomic-updates": "off"
我不认为这是一个错误。假设您的代码片段包含在异步函数中,即 doRequest
.
只要 ctx
变量定义在 doRequest
之外,ctx.body
赋值就处于竞争状态。因为无法保证赋给ctx.body
的最后一个值属于doRequest
.
的最后一次调用
我写了 a blog post 关于这个竞争条件。有两种方法可以避免此警告
方法 1:将 ctx
移动到 doRequest
主体中,然后 return 函数末尾的 ctx
值。
方法二:使用promise-base-semaphore pattern
let ctxPromise
每当您发出请求时,请调用 ctxPromise = doRequest()
。
下面的代码在使用 ESLint 检查时导致了竞争条件:
let match = false
try {
match = await something()
} catch (err) {
// do something
}
if (match === false) {
// do something
}
编写这段代码的更好方法是什么?
编辑:
let request = ctx.request.body || {}
let password = request.password
let match = false
try {
match = await bcrypt.compare(password, 'xxxxx')
} catch (err) {
ctx.throw(401, err)
}
if (match === false) {
ctx.throw(401, 'invalid password')
}
ctx.body = {
message: 'logged in ok'
}
ESLint 错误:
Possible race condition:
ctx.body
might be reassigned based on an outdated value ofctx.body
require-atomic-updates
您可以安全地忽略警告:)
ESLint 旨在捕捉这样的东西:
let value = 0;
async function race() {
value += await Promise.resolve(1);
console.log(value);
}
race(); race();
在这种情况下,race
在堆栈上记忆 value
,await
一个滴答,然后写回 value
。由于其他代码同时运行,value
可能已经更改,然后更新可能会关闭......它不是原子的。
然而,在您的情况下,您从 ctx.request.body
读取并写入 ctx.body
,因此没有非原子更新。此外,可能没有其他中间件同时访问同一个 ctx
,因此不会有任何并发修改。因此,在您的情况下,这是一个误报,甚至怀疑这在任何方面都是肯定的(它可能是 ESLint 中的错误)。
我意识到这个答案有点晚了,但对于遇到这个问题的任何未来用户来说,要禁用这个规则,在你的 .eslintrc.json
或你使用的任何相关配置中,只需指定:
"require-atomic-updates": "off"
我不认为这是一个错误。假设您的代码片段包含在异步函数中,即 doRequest
.
只要 ctx
变量定义在 doRequest
之外,ctx.body
赋值就处于竞争状态。因为无法保证赋给ctx.body
的最后一个值属于doRequest
.
我写了 a blog post 关于这个竞争条件。有两种方法可以避免此警告
方法 1:将 ctx
移动到 doRequest
主体中,然后 return 函数末尾的 ctx
值。
方法二:使用promise-base-semaphore pattern
let ctxPromise
每当您发出请求时,请调用 ctxPromise = doRequest()
。