2017-10-18 53 views
1

我正在读一本关于节点的设计模式,这是从99页here一些代码:部分应用mkdirp使用Function.prototype.bind()

function download(url, filename, callback) { 
    console.log(`Downloading ${url}`); 
    let body; 

    async.series([ 
    callback => {         //[1] 
     request(url, (err, response, resBody) => { 
     if(err) { 
      return callback(err); 
     } 
     body = resBody; 
     callback(); 
     }); 
    }, 

    mkdirp.bind(null, path.dirname(filename)),  //[2] 

    callback => {         //[3] 
     fs.writeFile(filename, body, callback); 
    } 
    ], err => {          //[4] 
    if(err) { 
     return callback(err); 
    } 
    console.log(`Downloaded and saved: ${url}`); 
    callback(null, body); 
    }); 
} 

我不是在之后//[2]会发生什么。这本书说你部分应用绑定功能。根据我对mdn here的理解,当您使用bind时,您不会调用该函数。

如果您以后不打电话mkdirp(),该代码如何工作?是否在fs.writeFile中使用callback参数进行引用?

我对此有一个潜在的解决方案。您可以通过async.series列出将要执行和执行的功能。 mozilla mdn表示绑定返回一个准备执行的函数。如果您使用callapply您将获得该功能的结果。 async.series想要一个函数执行,所以你使用绑定,让它坐在那里准备好没有它运行。

回答

1

您误解了代码。 mkdirp.bind(...在代码中的任何地方都没有调用,但是在async.series调用中,更确切地说是在其参数声明(数组[])中。 async.series将包含函数引用的数组作为参数,并按顺序依次调用它们。

  1. //[1]叫,
  2. 然后//[2]被称为这是参考mkdirp已经与参数绑定的(你可以看到一个例子here
  3. 等等...

为了让你更清楚,代码可以这样写:

function download(url, filename, callback) { 
    console.log(`Downloading ${url}`); 
    let body, 
    getFile = callback => { 
     request(url, (err, response, resBody) => { 
     if (err) { 
      return callback(err); 
     } 
     body = resBody; 
     callback(); 
     }); 
    }, 
    boundMkdirp = mkdirp.bind(null, path.dirname(filename)), 
    writeFile = callback => { 
     fs.writeFile(filename, body, callback); 
    }; 

    async.series([ 
    getFile, 
    boundMkdirp, 
    writeFile 
    ], err => { 
    if (err) { 
     return callback(err); 
    } 
    console.log(`Downloaded and saved: ${url}`); 
    callback(null, body); 
    }); 
}