2014-10-01 156 views
2

我想寫一個驗證函數,驗證我的請求標題。如果所有標題都正確,它將返回true,如果有錯誤,則返回false。我爲每個(幾乎)請求執行這個函數。問題是,我不知道如何返回主函數,以防使用回調並設置任何標誌不起作用,這是由於變量作用域的一些問題。當我在沒有回調的情況下工作時,一切都很好,我只是用下劃線來查詢我的JSON。現在我使用NeDB,並綁定回調我無法完成工作。 我試圖使用全局「res」變量,但問題是,當我將參數「cnt」的值(如果未找到令牌時爲0,如果有令牌時爲1)分配給「res」,則值「 RES」永遠是落後1次迭代‘CNT’:即:如何使用回調函數通過nodejs中的嵌套函數從主函數返回?

request1 (valid): cnt = 1; res = undefined; 
request2 (valid): cnt = 1; res = 1; 
request3 (invalid): cnt = 0; res = 1; 
request4 (valid): cnt = 1; res = 0; 

所有我想要做的是與真,如果返回的主要功能‘CNT’= 1,否則爲false‘CNT’= 0,要麼全局變量的幫助或使用其他方法。

function validateHeaders(request) { 
    if (request.headers.username && request.headers.deviceid) { 

     if (...) { 
      function getResult(callback) { 
       db.tokens.count({... 
       }, function (err, cnt) { 
        if (err) { 
         console.log(err); 
        } else { 
         callback(cnt); 
        } 
       }); 
      } 

      getResult(function (cnt) { 
       res = cnt; 
       console.log({ 
        count: cnt 
       }); 
      }); 

      console.log({ 
       result: res 
      }); 
     } else { 
      return false; 
     } 
    } else { 
     return false; 
    } 
} 
+0

由於函數裏面有一個異步函數,在完成之前不應該返回,所以您需要通過添加回調來使主函數「validateHeaders」異步。 – 2014-10-01 15:14:39

+0

「異步」表示函數被輸入到要運行的事件隊列中 - 最早的*爲* - 當前同步函數完成時。因此,JavaScript引擎嚴格保證'validateHeaders'將在任何異步操作開始之前完全運行並返回一個值(例如回調到'db.tokens.count')。 – apsillers 2014-10-01 15:33:06

+0

這基本上是[如何從Ajax調用返回響應?]的副本(http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) - 用'db.tokens.count'簡單替換「Ajax成功函數」。其他類似的問題是[瞭解Node.js處理順序](http://stackoverflow.com/q/14564408/710446)和[如何從javascript同步調用indexeddb方法](http://stackoverflow.com/q/13972243/710446) – apsillers 2014-10-01 15:35:54

回答

1

您不能從內部執行異步,非阻塞操作的函數中返回一個有意義的值。你需要做的,而不是什麼是傳遞一個回調:

function validateHeaders(request, cb) { 
    if (request.headers.username && request.headers.deviceid) { 
    if (...) { 
     db.tokens.count({ 
     // ... 
     }, function (err, cnt) { 
     if (err) { 
      cb(err); 
     } else { 
      cb(null, cnt === 1); 
     } 
     }); 
     return; 
    } 
    } 
    cb(null, false); 
} 

然後使用它像:

validateHeaders(req, function(err, success) { 
    if (err) throw err; // TODO: improve error handling 
    console.log(success); 
}); 
+0

工程就像一個魅力 - 非常感謝! :) – 2014-10-02 08:59:31

0

,如果你想使用的的NodeJS回調函數的返回值。你不能以同步風格使用它。你可以遵守nodejs的約定。

function validateHeaders(request, cb) { 
    if (request.headers.username && request.headers.deviceid) { 

     if (...) { 
      function getResult(callback) { 
       db.tokens.count({... 
       }, function (err, cnt) { 
        callback(err, cnt); 
       }); 
      } 

      getResult(function (err, cnt) { 
       if (err) { 
        cb(err); 
       } else { 
        if (cnt === 0) 
         cb(null, false); 
        else 
         cb(null, true);      
       } 
      }); 
     } else { 
      cb(null, false) 
     } 
} 

您可以使用回調結果。 注意:不要在異步函數中使用return。使用回調來傳遞值。 nodejs風格的回調函數有2個參數。第一個是錯誤,第二個是結果。