我正在阅读一本关于节点设计模式的书,这是第99页here中的一些代码:
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]
发生的事情。书中说你正在使用bind部分应用这个功能。根据我对mdn here的理解,当你使用bind
时,你不会调用该函数。
如果您稍后不致电mkdirp()
,此代码如何运作?它是否与callback
中的fs.writeFile
参数一起引用?
我有一个潜在的解决方案。您将async.series
一个函数列表交给它并执行。 mozilla mdn表示bind返回一个准备执行的函数。如果您使用call
或apply
,您将获得该功能的结果。 async.series
希望执行一个函数,这样你就可以使用bind让它在没有运行的情况下准备就绪。
答案 0 :(得分:2)
你误读了代码。 mkdirp.bind(...
在代码中的任何位置都没有被调用,但在async.series
调用内部,更确切地说是在其参数声明(数组[]
)内。 async.series
将包含函数引用的数组作为参数,并按顺序调用它们,一个接一个地调用它们。
//[1]
被调用,//[2]
,这是对已经与参数绑定的mkdirp
的引用(您可以看到示例here)为了让你更清楚,代码可以用这种方式编写:
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);
});
}