解释代码是如何工作的

时间:2017-03-17 03:34:23

标签: javascript node.js closures

考虑以下节点模块。它会在指定的秒数内生成一个睡眠过程并返回其PID。它会在进程退出时触发提供的回调。

//module.js    
const spawn = require('child_process').spawn;                                                                               
function run(delay, cb) {                                                                                                   
    var args = [delay];                                                                                                     
    var process = spawn('sleep', args);                                                                                     

    (function(process, cb) {                                                                                                
        process.on('close', (code, signal) => {                                                                             
            cb(process.pid);                                                                                                
        });                                                                                                                 
    })(process, cb);                                                                                                        

    return process.pid;                                                                                                     
}                                                                                                                           

module.exports = {                                                                                                          
    run: run                                                                                                                
}

测试代码调用模块三次并保存pid以及不同的字符串以区分回调。

var sleep = require("module");                                                                               
var pids = {};                                                                                                              

var cb = function(pid) {                                                                                                    
    console.log(pids[pid]);                                                                                                 
}                                                                                                                           

pids[sleep.run(1, cb)] = 'cb1';                                                                                             
pids[sleep.run(2, cb)] = 'cb2';                                                                                             
pids[sleep.run(3, cb)] = 'cb3';

代码完美运行,输出为:

cb1
cb2
cb3

我的困惑源于这样一个事实:即使没有模块中的闭包,代码也能完美运行,如下所示:

const spawn = require('child_process').spawn;                                                                            
function run(delay, cb) {                                                                                                
    var args = [delay];                                                                                                  
    var process = spawn('sleep', args);                                                                                  

    //(function(process, cb) {                                                                                           
        process.on('close', (code, signal) => {                                                                          
            cb(process.pid);                                                                                             
        });                                                                                                              
    //})(process, cb);                                                                                                   

    return process.pid;                                                                                                  
}                                                                                                                        

module.exports = {                                                                                                       
    run: run                                                                                                             
}     

我没想到代码在没有闭包的情况下运行。调用第一个/第二个回调时进程的值是多少?它不是第三个过程的价值吗?

1 个答案:

答案 0 :(得分:0)

函数(code, signal) => { cb(process.pid); }仍然是模块中的闭包。它关闭的范围由run函数提供(包含变量delaycbargsprocess),而不是IIFE(其范围仅包含隐藏process中的变量的cbrun变量。