如何在节点js中同步我的函数调用?

时间:2015-12-15 03:00:28

标签: javascript angularjs node.js

这是我的routes.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 thing@@');
    //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请求被发送到' / books /:bookId'它叫这个控制器:

功能($范围,$ routeParams,$ HTTP){

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

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

unnecessary thing@@
undefinedhello
GET /api/book/1 304 16.577 ms - -

在我的客户端控制台中,我得到了响应

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

在我的服务器端控制台中,在id = 1之前调用getBookDetails甚至可以通过' / api / book / 1'来传递。为什么会这样?为什么它不同步?我应该学习异步吗?

谢谢

1 个答案:

答案 0 :(得分:0)

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

一种更简单的方法是使用promises。学习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 thing@@');
    //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;
        }
    })
}