为什么在 while 表达式中使用 await 赋值不保留赋值? [英] Why does assignment using await within while expression not retain assigned value?
问题描述
给定 JavaScript 代码
Given the JavaScript code
function* gen(start = 0, stop = 5) {
while (start < stop) yield ++start;
}
async function fn(g = gen()) {
while (done = !await new Promise(resolve =>
setTimeout(resolve, 1000, g.next()))
.then(({value, done}) => {
// `value:undefined, done:true` following
// `value:5, done:false`
console.log(`value:${value}, done:${done}`);
return done
}
, err => Promise.reject(err)));
return done; // what happened to the `true` value assigned?
}
// why is `res` `false`?
fn().then(res => console.log(`res:${res}`), err => console.error(err));
当done
被赋值时,fn()
返回的done
的预期结果是true
code>true 从 .then()
在 while
表达式中返回.
the expected result of done
returned from fn()
is true
when done
is assigned the value true
that is returned from .then()
within while
expression.
推荐答案
JavaScript 有三种"不同类型的作用域:局部、全局和块.
JavaScript has "three" different types of scope: local, global, and block.
全球
这种类型的变量在代码的所有地方都可以到达:
This type of variable can be reach in all places of the code:
var b = "bar";
(function test1(a) {
if (a == true) {
var b = "bar";
} else {
var b = "foo";
}
return b;
})(true);
alert(b);
本地
这些变量只有在代码的一般范围内才能到达:
These variables can only be reached if the variable in the general scope of the code:
(function test2(a) {
if (a == true) {
var b = "bar";
} else {
var b = "foo";
}
return b;
})(true)
在这种情况下,一般作用域是函数.即使变量 b
是 if 语句的块作用域,函数仍然可以访问它.
In this case, the general scope is the function. Even though the variable b
is block scoped by the if statement, the function can still reach it.
阻止
自定义块作用域变量对于 JavaScript 来说是非常新的,可以使用 let
关键字引入:
Self defined block scoped variables are pretty new to JavaScript and can be introduced using the let
keyword:
(function test2(a) {
if (a == true) {
let b = "bar";
} else {
let b = "foo";
}
return b;
})(true)
这将导致错误,因为变量 b
现在块作用域为 if 状态.因此,在您的代码中,我们可以更改您的范围,以允许您更改 done 在异步循环的情况下,在 while 循环中是块范围的.
This will result in an error because the variable b
is now block scoped to the if state. Thus in your code, we can change your scoping to allow you to change done which in a while loop is block scoped in the case of asynchronous loops.
function* gen(start = 0, stop = 5) {
while (start < stop) yield ++start;
}
async function fn(g = gen()) {
let doneVal;
while (done = !await new Promise(resolve =>
setTimeout(resolve, 1000, g.next()))
.then(({value, done}) => {
// `value:undefined, done:true` following
// `value:5, done:false`
console.log(`value:${value}, done:${done}`);
return done
}
, err => Promise.reject(err))) {
doneVal = done;
}
return doneVal; // what happened to the `true` value assigned?
}
// why is `res` `false`?
fn().then(res => console.log(`res:${res}`), err => console.error(err));
现在您将获得 res:true
.在您的具体示例中,这样的代码存在问题:
Now you will get res:true
. In your specific example, there is an issue with code like this:
var i;
var c = 0;
while (i = 90 && c < 10) {
c++;
}
console.log(i, c);
i
为假而 c
等于 10
i
is false while c
is equal to 10
这篇关于为什么在 while 表达式中使用 await 赋值不保留赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!