kno*_*ona 5 javascript assignment-operator promise es6-promise
我正在做一些事情,但遇到了一个我无法理解的问题。我简化了代码以获得:
function somePromise() {
return new Promise((resolve, reject) => {
resolve(1);
});
}
async function main() {
let count = 0;
const arr = [1, 2, 3, 4, 5];
const promises = arr.map(async () => {
count += await somePromise();
})
await Promise.all(promises);
console.log(count);
}
main().then(() => console.log('Done'));Run Code Online (Sandbox Code Playgroud)
你期待什么结果?
1
完成
已记录。
当我改变
count += await somePromise();
Run Code Online (Sandbox Code Playgroud)
到
const nb = await somePromise();
count += nb;
Run Code Online (Sandbox Code Playgroud)
我得到
5
完成
我第一次期待的。
你能帮我找出问题所在吗?我不明白。
当解释器遇到 时await,它会暂停函数,直到 Promise 解决。即使 Promise 立即解析,该函数也只会在下一个微任务期间恢复。与此相反,该阵列是通过迭代立即,同步。当你做
const promises = arr.map(async () => {
count += await somePromise();
})
Run Code Online (Sandbox Code Playgroud)
数组迭代后通过,但之前的await■找解决的“当前”值count这是采取通过使用+=检索之前的await做出决议-和值count在此之前是0,所以,它看起来解释为如果有 5 个单独的语句:
count += await somePromise();
count += await somePromise();
count += await somePromise();
count += await somePromise();
count += await somePromise();
Run Code Online (Sandbox Code Playgroud)
解决了类似的问题
const currentValueOfCount = count;
count = currentValueOfCount + await somePromise();
count = currentValueOfCount + await somePromise();
count = currentValueOfCount + await somePromise();
count = currentValueOfCount + await somePromise();
count = currentValueOfCount + await somePromise();
Run Code Online (Sandbox Code Playgroud)
因此,每次,右侧都=解析为0 + 1,因此在循环结束时,count仅为 1。
如果您对规范中的描述感兴趣,请查看赋值运算符的语义。where+=是AssignmentOperators 之一,语法如下:
LeftHandSideExpression AssignmentOperator AssignmentExpression
做:
- 令 lref 为评估 LeftHandSideExpression 的结果。
- 让 lval ? 获取值(lref)。
- 让 rref 是对 AssignmentExpression 求值的结果。
- 让 rval ? 获取值(参考)。
- 令 op 为 @,其中 AssignmentOperator 为 @=。
- 令 r 是将 op 应用于 lval 和 rval 的结果,就像评估表达式 lval op rval 一样。
在评估运算符的右侧之前,查看如何立即lval检索。(如果在右手边之后被检索,则lvalAssignmentExpression,是进行评价的结果将是5,因为你希望)
这是没有异步操作的这种行为的示例:
const promises = arr.map(async () => {
count += await somePromise();
})
Run Code Online (Sandbox Code Playgroud)
上面,num += 2 + fn();检索numas5立即用于+=,然后调用fn()。虽然num是在 inside 中重新赋值fn,但它没有任何作用,因为 的值num已经被外部 检索到了+=。
使用您的工作代码,当您这样做时
const nb = await somePromise();
count += nb;
Run Code Online (Sandbox Code Playgroud)
这会将解析值somePromise放入nb变量中,然后 count += nb;运行。这符合预期,因为在Promise 解析后检索countused for的“当前”值,因此如果先前的迭代重新分配,下一次迭代将成功考虑。+=count
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |