ron*_*ved 31 javascript node.js
我的控制器中有一些函数可以调用一些数据库函数.所有这些数据库函数都执行"错误回调",这意味着如果发生数据库错误,它们会执行单独的回调来处理错误.例:
exports.referralComplete = function(req, res){
/*getting id etc.*/
db.startDatabaseConnection(function() {
db.flagReferralAsDone(id, function(success) {
db.endDatabaseConnection();
/*doing stuff on success*/
}, onError);
}, onError);
function onError(err, description) {
logger.error(description + ": " + err);
user.pageNotFound(req, res);
}
}
Run Code Online (Sandbox Code Playgroud)
我有多个与此类似的函数,它们调用不同的数据库函数.问题是我现在已经将onError()复制到每个的范围内,因为我在处理错误时需要req和res变量.我当然可以将res和req传递给数据库函数,然后将它们作为参数传递给错误回调,但我觉得可能有更好的方法.
所以问题是:是否有可能以某种方式将res和req绑定到全局onError回调函数,以某种方式我不必将变量作为参数传递给db函数?
我对node.js和javascript很新,所以如果有更好的方法来处理错误,请告诉我.
Tha*_*you 65
绑定很简单!
db.startDatabaseConnection(function(){
// whatever
}, onError.bind(this, var1, var2));
Run Code Online (Sandbox Code Playgroud)
您可以通过单击这个很棒的链接来了解有关绑定的更多信息,即使链接有点长.
这是一个真正的基本演示
// a function
var something = function (a, b, c) {
console.log(a, b, c);
};
// a binding of something with 3 defined args
var b = something.bind(null, 1, 2, 3);
// call b
b();
//=> 1 2 3
Run Code Online (Sandbox Code Playgroud)
在幕后,这基本上是正在发生的事情
// ES6
const myBind = (f, context, ...x) =>
(...y) => f.call(context, ...x, ...y);
// ES5
var myBind = function(fn, context) {
var x = Array.prototype.slice.call(arguments, 2);
return function() {
var y = Array.prototype.slice.call(arguments, 0);
return fn.apply(context, x.concat(y));
};
};
var b = myBind(console.log, console, 1, 2, 3);
b();
// => 1 2 3
b(4,5,6)
// => 1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)
语境?
Context允许您动态更改this函数.注意,您只能绑定使用function关键字定义的函数的上下文; 箭头函数有一个this无法操纵的词法.这是为了完整性而显示,但我建议不要使用这种程序.通常最好只使用另一个函数参数而不是依赖于动态函数上下文this.像这样支持上下文切换是为了在JavaScript中启用面向对象的样式.除非你使用这种风格,否则我认为没有理由关注背景.
const getCanvas = (id) =>
document.getElementById(id).getContext('2d')
const draw = function (canvas, x = 0, y = 0)
{ canvas.beginPath()
canvas.strokeStyle = this.color // `this` refers to context!
canvas.rect(x, y, this.width, this.height) // `this` refers to context!
canvas.stroke()
}
// create two contexts
const contextA =
{ color: 'blue', width: 10, height: 10 }
const contextB =
{ color: 'green', width: 10, height: 20 }
// bind the draw function to each context and the canvas
const drawA =
draw.bind(contextA, getCanvas('main'))
const drawB =
draw.bind(contextB, getCanvas('main'))
// call the bound drawing functions normally
// draw three blue squares
drawA(0, 0)
drawA(20, 0)
drawA(40, 0)
// and one green rect
drawB(80, 0)Run Code Online (Sandbox Code Playgroud)
<canvas id="main"></canvas>Run Code Online (Sandbox Code Playgroud)
部分申请
类似的bindING是部分应用程序
在计算机科学中,部分应用(或部分功能应用)是指将一些参数固定到一个函数,产生另一个较小的arity函数的过程.
在这里,我们可以做一个非常简单的partial帮助程序,帮助我们实现这一目标
const identity = x =>
x
const partial = (f = identity, ...x) =>
(...y) => f (...x, ...y)
const foo = (...all) =>
console.log ('array of', all)
partial (foo, 1, 2, 3) (4, 5, 6)
// 'array of', [ 1, 2, 3, 4, 5, 6 ]Run Code Online (Sandbox Code Playgroud)
哗众取宠
Currying与绑定或部分应用有关,但不相同
在数学和计算机科学中,currying是一种翻译对函数的评估的技术,该函数将多个参数(或参数元组)转换为评估一系列函数,每个函数都有一个参数.
const identity = x =>
x
const curry = (f = identity, arity = f.length) => x =>
{
const next = (xs = []) =>
xs.length >= arity
? f (...xs)
: x => next ([ ...xs, x ])
return next ([ x ])
}
const foo = (a, b, c) =>
console.log ('a', a, 'b', b, 'c', c)
curry (foo) (1) (2) (3)
// 'a' 1 'b' 2 'c' 3
curry (foo) ('choo') ('bye') ()
// 'a' 'choo' 'b' 'bye' 'c' undefinedRun Code Online (Sandbox Code Playgroud)