Why does assignment using await within while expression not retain assigned value?

前端 未结 2 600
醉话见心
醉话见心 2020-12-22 13:36

Given the JavaScript code



        
2条回答
  •  情书的邮戳
    2020-12-22 14:33

    JavaScript has "three" different types of scope: local, global, and block.

    Global

    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);
    

    Local

    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)
    

    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.

    Block

    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)
    

    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));
    

    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 is false while c is equal to 10

提交回复
热议问题