2017-03-16 87 views
0

我有一個路徑做了一些處理,它應該返回一個回調。 這裏是代碼:node.js回調設計 - 如何在回調中使用res

router.get('/login', function(req,res,next) { 
    // send call to login function. 
    var ID= req.query.ID; 
    var Password = req.query.Password 

    ctlLogin.login(ID,Password, LoginCallback); 



}); 

function LoginCallback(err,myLoginResult) 
{ 
    res.json(myLoginResult); 
} 

的登錄功能檢查,如果用戶名/密碼的數據庫,並返回存在:

loginCallback(result); 

我的問題 - 在LoginCallBack溫控功能不知道對象資源。 我知道我可以將它傳遞給登錄模塊,只是爲了讓它作爲回調函數的參數傳遞給我,但它看起來像一個糟糕的設計,它足夠糟糕,我需要將回調函數發送到登錄方法。

有沒有更好的方法來做到這一點,仍然有可讀代碼?

+0

*「這是不好的使用bind

您的代碼重寫足夠我需要發送回調函數到登錄方法「*爲什麼? – 4castle

+0

我想同步工作。 – Dani

+0

我的意思是,你爲什麼認爲回調是壞設計?他們是相當標準的,但如果你想要一個替代品,你可以返回一個承諾。 – 4castle

回答

1

我認爲最好的辦法是使用這個代碼片段:

ctlLogin.login(ID,Password, function(myLoginResult){ 

      res.json(myloginResult); 

    }); 

在這種情況下,你應該在你的登錄功能是這樣的:

login(ID, Password, callback){ 
     //your treatment here 
     callback(result) 


    } 
+0

我試圖避免這種編碼嵌套形式 - 隨着它越來越深入。我雖然我的版本是平等的,但我想這不是... – Dani

1

您可以創建自己的中間件來處理您在不同功能上的登錄。下面是一個簡單的應用程序明確我爲你創建:

var app = require('express')(); 
var bodyParser = require('body-parser'); 

app.use(bodyParser.json()); 

function login(req, res, next) { 
    // login check 
    console.log(req.query); 
    if(req.query.ID === '1' && req.query.Password === 'password') { 
     return next(); 
    } 

    // if check above is false 
    res.send({success: false}); 
} 

app.get('/login', login, function (req, res, next) { 
    res.send({success: true}); 
}) 

app.listen(3000, function() { 
    console.log('Example app listening on port 3000!') 
}) 

你可以看到,我插在佈線後app.get('/login', login, func...功能。

現在,如果您使用這些url參數http://localhost:3000/login?ID=1&Password=password訪問網頁,您應該會看到成功消息。如果更改任何參數名稱或值,則應返回成功:false。

你應該多看一些關於製作自己Express Custom Middleware

+0

非常有趣,感謝文章參考。 – Dani

1

您正在使用loginCallback出的功能(REQ,水庫,旁邊),從而REQ,水庫範圍和未來超出範圍,他們無法訪問。你可以訪問這個喜歡

router.get('/login', function(req,res,next) { 
    // send call to login function. 
    var ID= req.query.ID; 
    var Password = req.query.Password 

    function LoginCallback(err,myLoginResult){ 
    res.json(myLoginResult); 
    } 

    ctlLogin.login(ID,Password, LoginCallback); 
}); 

,或者如果ctlLogin功能詢問服務承諾可以使用的承諾,而不是回調

ctlLogin.login(ID,Password) 
    .then(LoginCallback) 
    .catch(console.log(err)) 

,或者如果你想LoginCallback功能出的功能範圍(REQ,水庫,接下來),那麼你需要通過創建一個回調函數來傳遞該函數中的res,然後通過傳遞錯誤,結果和res或者使用bind來調用LoginCallback函數。

function sendResponseToSever(res, err, myLoginResult){ 
    if(err){ 
     return res.send({ 
       errors: err, 
       status: 500 // what ever status code you want to set 
     }); 
    } 
    return res.json(results); 
} 

    router.get('/login', function(req,res,next) { 
    // send call to login function. 
    var ID= req.query.ID; 
    var Password = req.query.Password  

    ctlLogin.login(ID,Password, sendResponseToSever.bind(null, res) 
     //using bind function 
     // OR 
    ctlLogin.login(ID,Password, function(err, myLoginResult){ 
     sendResponseToSever(err, myLoginResult, res); 
     // now sendResponseToSever is a generic function which you can call 
     // from any route 
    });   
    }); 
}); 

但是如果你想避免回調地獄,最好的方法是使用promise。 正如你所提到的你想避免嵌套,你可以通過使用promise來避免它。

請參閱https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise如果你想了解的承諾

1

我會在你的情況下使用(如果我們跳過使用承諾等更強硬的東西),該解決方案結合上下文的功能。 大多數情況下,它用於保留使用對象方法作爲回調的對象上下文,但它也可以用來創建一個函數,其參數比原來的要少(有時稱爲currying)。

在JavaScript中,您可以使用方法bind在任何函數上綁定上下文。第一個參數是函數調用期間的值this,其他參數值只是參數值。

router.get('/login', function(req,res,next) { 
    // send call to login function. 
    var ID= req.query.ID; 
    var Password = req.query.Password 

    ctlLogin.login(ID,Password, LoginCallback.bind(null, res)); 
}); 

function LoginCallback(res, err, myLoginResult) 
{ 
    res.json(myLoginResult); 
} 

```

1

這可以很容易地改製爲更readable使用代碼的承諾很少重構:

router.get('/login', function(req,res,next) { 
    // send call to login function. 
    var ID= req.query.ID; 
    var Password = req.query.Password 

    ctlLogin.login(ID,Password) 
     .then((result) => { 
     // handle success 
     }) 
     .catch((err) => { 
     // handle failure 
     }) 
}); 



function Login(ID, password) { 
    return new Promise(resolve, reject) { 
     // run your query using a library that supports promises 
     .then((result) => resolve(result)) 
     .catch((err) => { 
      //handle your error 
      reject(err) 
     }) 
    } 
}