How to avoid access mutable variable from closure

前端 未结 6 2035
醉梦人生
醉梦人生 2020-12-02 20:10

I have some code like this:

for(var id=0; id < message.receiver.length; id++){
   var tmp_id = id;
   zlib.gzip(JSON.stringify(message.json), function(err         


        
6条回答
  •  北荒
    北荒 (楼主)
    2020-12-02 21:13

    Creating closures in a loop with var (tmp_id) being in the upper scope of the callback function is a common mistake that should be avoided due to the var not being block-scoped. Because of this, and because each closure, created in the loop, shares the same lexical environment, the variable will always be the last iterated value (i.e. message.receiver.length - 1 as tmp_id) when the callback function gets invoked. Your IDE detects this behavior and complains rightly.

    To avoid the warning, there are several solutions:

    • Replace var with let ensuring each created closure to have its own scoped tmp_id defined in each iteration:

      for (var id = 0; id < message.receiver.length; id++) {
        let tmp_id = id;
        zlib.gzip(JSON.stringify(message.json), function(err, buffer) {
          // Do something with tmp_id ...
        });
      }
      
    • Create a lexical environment in each iteration by leveraging IIFE like gennadi.w did.

    • Create a callback function in each iteration by using a factory function (createCallback):

      const createCallback = tmp_id => function(err, buffer) {
        // Do something with tmp_id ...
      };
      for (var id = 0; id < message.receiver.length; id++) {
        zlib.gzip(JSON.stringify(message.json), createCallback(id));
      }
      
    • bind the variable(s) on the callback function in which they get prepended to its parameters:

      for (var id = 0; id < message.receiver.length; id++) {
        zlib.gzip(JSON.stringify(message.json), function(tmp_id, err, buffer) {
          // Do something with tmp_id (passed as id) ...
        }.bind(this, id));
      }
      

    If possible, var should be avoided as of ECMAScript 2015 due to such error-prone behaviors.

提交回复
热议问题