我的问题是下载未知扩展程序的图片(可能是' png'或者' jpg'或者' bmp'或等等...)。功能chekHead的返回值有一些麻烦:
var fs = require('fs'),
request = require('request');
var processImg = function (uri,filename){
if(checkHead(uri + 'png') > 2000){
download(uri + 'png', filename + '.png', function(){
console.log(uri + 'png' + " - downloaded")
})
}else if(checkHead(uri + 'jpg') > 2000){
download(uri + 'jpg', filename + '.jpg', function(){
console.log(uri + 'jpg' + " - downloaded")
})
}else if(checkHead(uri + 'bmp') > 2000) {
download(uri + 'bmp', filename + '.bmp', function () {
console.log(uri + 'bmp' + " - downloaded")
})
}
}
var checkHead = function(uri){
var length;
request.head(uri, function(err, res, body){
if(err) return console.log("Error");
length = res.headers['content-length'];
console.log(length);
});
return length;
}
var download = function(uri, filename, callback){
request(uri).pipe(fs.createWriteStream('./static/' + filename).on('close', callback));
};
因此,在 checkHead 函数返回长度; 始终返回' underfined',但console.log返回有效数字;为什么呢?
答案 0 :(得分:4)
NodeJS使用回调以异步方式执行代码。您的返回可能发生在之前(在这种情况下可能总是如此)回调完成。变量length
位于return
未定义,因为它未收到任何值。
您可以使用promises来链接函数,或者以另一种方式构建代码。
var checkHead = function(uri){
var length;
// Callback is probably invoked after the return
request.head(uri, function(err, res, body){
if(err) return console.log("Error");
length = res.headers['content-length'];
console.log(length);
});
// gets executed directly
return length;
}
答案 1 :(得分:2)
您必须使用回调,以便按您希望的方式运行:
var checkHead = function(uri,callback){
request.head(uri, function(err, res, body){
if(err) return console.log("Error");
var length = res.headers['content-length'];
console.log(length);
callback(length);
});
};
不幸的是,由于你的if-else逻辑,我认为目前没有办法使用promises(jquery)而不是回调和嵌套回调可能导致回调 - 地狱这是一种糟糕的模式,所以我对此抱歉:
checkHead(uri + 'png',function(length){
if(length > 2000){
download(uri + 'png', filename + '.png', function(){
console.log(uri + 'png' + " - downloaded")
});
}
else{
checkHead(uri + 'jpg',function(length){
if(length > 2000){
download(uri + 'jpg', filename + '.jpg', function(){
console.log(uri + 'jpg' + " - downloaded")
});
}
else{
checkHead(uri + 'bmp',function(length){
if(length > 2000){
download(uri + 'jpg', filename + '.jpg', function(){
console.log(uri + 'jpg' + " - downloaded")
});
}
});
}
});
}
});
<强> BUT 强> EcamScript 6负责这一点。关于生成器函数,这是一个很好的article。主要思想是为异步方法或函数使用yield,例如 request.head :
var checkHead = function*(uri){
var length = yield request.head(uri);
};
然后使用next to get length:
checkHead.next();//{value: 123, done: true}
这只是我的概念,我没有证明这一点,但生成器函数符号以这种方式工作:)