2013-07-17 142 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