为什么在表达式中使用await的赋值不保留赋值?

时间:2017-11-08 04:13:53

标签: javascript while-loop ecmascript-6 async-await ecmascript-next

给出JavaScript代码

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()的预期结果为truedone被分配了true内从.then()返回的值while public class PlayerSprite extends Rectangle { private String name; private int playerID; final int TILE = 32; final int SIZE = 4; public PlayerSprite(PlayerCharacter player, int id, Paint color) { super(4, 4, color); //Currently a player takes up 4 points this.name = player.getName(); this.playerID = id; } public int getPlayerSize() { return SIZE; } } 表达。

为什么在await声明while使用expression的作业未被保留?

2 个答案:

答案 0 :(得分:2)

JavaScript具有“三种”不同类型的范围:local,global和block。

<强>全球

这种类型的变量可以在代码的所有位置到达:

var b = "bar";
   (function test1(a) {
         if (a == true) {
              var b = "bar";
         } else {
              var b = "foo";
         }
         return b;
    })(true);
    alert(b);

本地

只有在代码的一般范围内的变量:

时才能达到这些变量
(function test2(a) {
     if (a == true) {
          var b = "bar";
     } else {
          var b = "foo";
     }
     return b;
})(true)

在这种情况下,一般范围是功能。即使变量b是if语句的块作用域,函数仍然可以到达它。

阻止

自定义的块范围变量对JavaScript来说是一个新手,可以使用let关键字引入:

(function test2(a) {
     if (a == true) {
          let b = "bar";
     } else {
          let b = "foo";
     }
     return b;
})(true)

这将导致错误,因为变量b现在被块作用于if状态。因此,在您的代码中,我们可以更改您的作用域,以允许您在异步循环的情况下更改while循环中的块作用域。

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。在您的具体示例中,代码存在问题:

var i;
var c = 0;
while (i = 90 && c < 10) {
    c++;
}
console.log(i, c);
i等于10

时,

c为false

答案 1 :(得分:1)

@JaromandaX的评论有助于认识到!在代码中的位置不正确,无法返回预期结果。 @ Shawn31313的答案提醒在函数调用中使用参数或let定义变量,因为done被定义为全局变量不是

function* gen(start = 0, stop = 5) {
   while (start < stop) {
     yield ++start;
   }
}
async function fn(g = gen()) {
  let done;
  while ((done = await new Promise(resolve => 
                   setTimeout(resolve, 1000, g.next()))
                   .then(({value, done}) => {
                     console.log(value, done); 
                     return !done
                   }
                   , err => Promise.reject(err))));
  return !done;
}

fn().then(res => console.log(res), err => console.error(err));