2013-07-17 58 views
25

我的控制器中有一些函数调用某些数据库函数。所有这些数据库函数都会执行“错误回调”,这意味着如果发生数据库错误,它们将执行单独的回调来处理错误。例如:将变量绑定到回调函数

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); 
    } 
} 

我有很多类似这个的函数,它们调用不同的数据库函数。问题是我目前已经将onError()复制到它们中的每一个的范围中,因为在处理错误时我需要req和res变量。我当然可以将res和req传递给数据库函数,然后将它们作为参数传递给错误回调函数,但我认为可能有更好的方法。

所以问题是:是否有可能以某种方式将res和req绑定到全局onError回调函数,这样我就不必将变量作为参数传递给db函数了?

我对node.js和javascript一般都很陌生,所以如果有更好的处理错误的方法,请告诉我。

回答

46

绑定很简单!

db.startDatabaseConnection(function(){ 
    // whatever 
}, onError.bind(this, var1, var2)); 

You can learn more about binding by clicking this awesome link, even though the link is sort of long

这里是一个真正的基本演示

// 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 

在幕后,这基本上是发生了什么事

// 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 

局部应用

类似bind ING是Partial Application

在计算机科学中,部分应用程序(或部分功能应用程序)是指将一些参数固定到一个函数,产生另一个较小函数的函数的过程。

在这里我们可以做一个非常简单的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 ]


钻营

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' undefined

+2

的联系是很长,但内容它指向,没有那么多! :) – bfavaretto