JavaScript中的条件链函数
我正在尝试重构以下node.js代码 每个案例生成一个缩略图,将一组不同的GraphicMagic转换链接到一个图像JavaScript中的条件链函数,javascript,node.js,graphicsmagick,Javascript,Node.js,Graphicsmagick,我正在尝试重构以下node.js代码 每个案例生成一个缩略图,将一组不同的GraphicMagic转换链接到一个图像 switch(style.name) { case 'original': gm(response.Body) .setFormat('jpg').autoOrient().resize(style.w, style.h, style.option) .toBuffer(function(err, buffe
switch(style.name) {
case 'original':
gm(response.Body)
.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option)
.toBuffer(function(err, buffer) { if (err) { next(err); } else { next(null, buffer); } });
break;
case 'large':
gm(response.Body)
.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option)
.quality(style.quality)
.strip().interlace('Plane')
.toBuffer(function(err, buffer) { if (err) { next(err); } else { next(null, buffer); } });
break;
case 'medium':
gm(response.Body)
.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option)
.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset)
.repage('+')
.strip().interlace('Plane')
.toBuffer(function(err, buffer) { if (err) { next(err); } else { next(null, buffer); } });
break;
case 'small':
gm(response.Body)
.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option)
.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset).repage('+')
.quality(style.quality)
.strip().interlace('Plane')
.toBuffer(function(err, buffer) { if (err) { next(err); } else { next(null, buffer); } });
break;
}
然而,所有案例在链接的开始和结束时都有许多转换,因此有重构的空间。我尝试使用以下方法进行重构,但代码似乎不正确:
gm(response.Body)
.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option, function(err, response) {
if (style.name === 'original'){
return response;
} else if (style.name === 'large'){
return response.quality(style.quality)
} else if (style.name === 'medium'){
return response.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset).repage('+')
} else if (style.name === 'small'){
return response.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset).repage('+').quality(style.quality)
}
}).(function(response) {
return (stryle.name !== 'original') ? response.strip().interlace('Plane') : return response;
}).(function(argument) {
return response.toBuffer(function(err, buffer) { if (err) { next(err); } else { next(null, buffer); } });
});
我根本不会选择
开关
这里根本没有理由使用链接。照办
// if (!/^(original|large|medium|small)$/.test(style.name)) throw new Error(…);
var x = gm(response.Body)
.setFormat('jpg')
.autoOrient()
.resize(style.w, style.h, style.option);
if (style.name == "medium" || style.name == "small")
x = x.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset)
.repage('+');
if (style.name == "large" || style.name == "small")
x = x.quality(style.quality);
if (style.name == "large" || style.name == "medium" || style.name == "small")
// possibly better than if (style.name != "original")
x = x.strip()
.interlace('Plane');
x.toBuffer(next);
但是,如果您有大量的选项,因此无法读取,最好将函数中的每个转换都考虑在内:
function resizedJpg(x) {
return x.setFormat('jpg').autoOrient().resize(style.w, style.h, style.option);
}
function cropped(x) {
return x.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset).repage('+');
}
function withQuality(x) {
return x.quality(style.quality);
}
function stripped(x) {
return x.strip().interlace('Plane');
}
然后分别应用它们:
({
original: [resizedJpg],
large: [resizedJpg, withQuality, stripped],
medium: [resizedJpg, cropped, stripped],
small: [resizedJpg, cropped, withQuality, stripped]
}[style.name]).reduce(function(x, trans) {
return trans(x);
}, gm(response.Body)).toBuffer(next);
我为这样的用例编写了小型js助手:
借助此工具,您可以根据条件选择链接方法。
代码将更易于控制和阅读
cond(gm(response.Body)
.setFormat('jpg')
.autoOrient()
.resize(style.w, style.h, style.option))
.if(style.name == 'medium' || style.name == 'small', gm => gm
.crop(style.w, style.h, style.crop.x_offset, style.crop.y_offset)
.repage('+'))
.if(style.name == 'large' || style.name == 'small', gm => gm
.quality(style.quality))
.if(style.name != 'original', gm => gm
.strip()
.interlace('Plane'))
.end().toBuffer(next)
)。(
另外,一个可读性更强的对象{“original”:resp1,“normal”:resp2,等等。}
嗯,我没有看到调整大小
使用函数(错误,响应)
callback在第一个代码段中?谢谢你的回答!对于第一种方法,由于我们不是一次链接所有方法并使用中间变量x,它会单独运行gm转换(在if语句之前一次,之后两次),还是在调用toBuffer()时一次执行所有转换
?我担心多次调用转换也会在图像上多次运行gm,因此计算成本比一次链接所有转换并在图像上只运行一次gm要高。@SBBS:No,gm
无法区分它是否分配给变量,只要链是同步执行的。使用这种生成器模式,我很确定只有在调用.toBuffer()
时才会执行此工作。如果编写得很好,您可以在同一时间调用.toBuffer()
两次,它将正好运行两次。