2015-12-15 51 views
2

这里是我的routes.js如何在节点js中同步我的函数调用?

app.route('/api/book/:id') 
     .get(function(req,res){ 
      var id=req.params.id; 
      bookapi.getBookDetails(id,res); 
     }); 

,这里是它

scope.getBookDetails=function(bookId,res){ 
    console.log('unnecessary [email protected]@'); 
    //var bookId=req.params.id; 
    connection.query({ 
     sql:"SELECT name,description FROM books WHERE books.id=?", 
     values:[bookId] 
    }, 
    function (err,results) { 
     if(err) throw err; 

     if(results.length>0){ 
      var x=scope.getGenre(bookId); 
      console.log(x +"hello"); 
      res.send(JSON.stringify(results)+scope.getAuthors(bookId)+scope.getGenre(bookId)); 
     } 
    } 
    ) 
} 

我使用的角度也因此,当一个GET请求发送到调用函数“/书/:BOOKID”调用该控制器:

函数($范围,$ routeParams,$ HTTP){

$http.get('/api/book/'+$routeParams.bookId).success(function(bookdetails){ 
      $scope.bookdetails=bookdetails; 
     }) 
    } 

这是我的服务器端的控制台:

unnecessary [email protected]@ 
undefinedhello 
GET /api/book/1 304 16.577 ms - - 

在我的客户端控制台我得到的回应

[{"name":"The Alchemist","description":""}]undefinedundefined 

在我的服务器端控制台getBookDetails被ID = 1甚至可以通过调用之前通过'/ api/book/1'。这是为什么发生?为什么它不同步?我应该学习异步吗?

谢谢

回答

0

分配req.params.id一个变量id始终是同步的,所以这个问题是不存在的。问题可能是因为getGenregetAuthors是异步的,所以必须将依赖于结果的任何内容移动到回调函数中。

一个简单的方法是使用承诺。学习JavaScript承诺库非常有趣,是bluebird。它应该让事情变得更容易。

app.route('/api/book/:id') 
    .get(function(req,res){ 
     var id=req.params.id; 
     bookapi.getBookDetails(id).then(function(result){ 
      res.send(result) 
     }); 
    }); 

scope.getBookDetails=function(bookId){ 
    console.log('unnecessary [email protected]@'); 
    //var bookId=req.params.id; 
    return Promise.promisify(connection.query)({ 
     sql:"SELECT name,description FROM books WHERE books.id=?", 
     values:[bookId] 
    }) 
    .then(function (results) { 
     if(results.length>0){ 
      return Promise.props({ 
       // getGernre should return a promise just like this function. 
       // if it accepts a callback, you can do 
       // Promise.promisify(scope.getGenre) and use that instead 
       genre: scope.getGenre(bookId), 
       authors: scope.getAuthors(bookId), 
       results: results, 
      }) 
     } 
    }) 
    .then(function (dict){ 
     if(dict){ 
      console.log(dict.genre +"hello"); 
      return JSON.stringify(dict.results)+dict.authors+dict.genre; 
     } 
    }) 
} 
+0

谢谢你的时间。承诺似乎是一个可行的解决方案。但是,我仍然不明白为什么getBookDetails函数在GET/api/book/1请求被发送之前被调用。 – She

+0

它没有,你可以在getBookDetails的开头写'console.log(bookId)',它应该打印1 – MIE

+0

这让我发疯,有时间回头去学习,从一开始就学习东西。使用回调会导致功能太多。使用承诺意味着我必须再次学习新的东西。 – She