等待同步

时间:2016-11-23 13:24:44

标签: javascript node.js asynchronous callback

我正在使用Express JSmysql2-node模块创建一个访问MySQL数据库的函数

indexOfUserInVotingList

indexOfUserInVotingList: function (voteType, articleID, userID) {
        SQLconnection.connectToServer();
        db = SQLconnection.getConnectionInstance();
        let userIndex;
        switch (voteType) {
            case "upvote":
                db.query('SELECT upVoters FROM article WHERE article.idArticle = ?', [articleID], function (err, rows) {
                    if (err) {
                        throw err;
                    } else {
                        let upvoterArray = rows[0].upVoters;
                        userIndex = upvoterArray.indexOf(userID);
                    }
                });
                break;
            case "downvote":
                db.query('SELECT downVoters FROM article WHERE article.idArticle = ?', [articleID], function (err, rows) {
                    if (err) {
                        throw err;
                    } else {
                        let downvoterArray = rows[0].downVoters;
                        userIndex = downvoterArray.indexOf(userID);
                    }
                });
                break;
            default:
                break;
        }
        return userIndex;
    }

我在这个函数中调用了这个函数 - upvoteInArticleFromUser ,需要该userID的索引才能工作:

upvoteInArticleFromUser: function (articleID, userID, callback) {
        SQLconnection.connectToServer();
        db = SQLconnection.getConnectionInstance();
        let userIndex = this.indexOfUserInVotingList('upvote',articleID,userID);
        console.log("userIndex: "+userIndex);
        // the rest of the code was cut shorted...
    }

我得到了结果:

  

userIndex:undefined

我在return运行之前立即执行 indexOfUserInVotingList 中的mysql-query操作并更新了该值。

无论如何我可以强制 indexOfUserInVotingList 等待查询完成并返回结果吗?

最重要的一点是,我不想把它变成异步功能(尽管这种方法可行):

indexOfUserInVotingList: function (voteType, articleID, userID, callback) {
     //......... 
     //after query from database
     return callback(null,userIndex);
    }

..因为我不想陷入 callbackhell ,例如:

upvoteInArticleFromUser: function (articleID, userID, callback) {
       //.....


       indexOfUserInVotingList('upvote',articleID,userID,function(err,index){
            if(err) throw err;
            else
            {
                this.userIndex = index;
                // the whole remaining code for processing would be nested inside this one...
            }
 }

2 个答案:

答案 0 :(得分:1)

由于node.js正在使用非阻塞I / O模型,因此在涉及I / O操作时无法在不等待回调的情况下获取数据。

如果您有“厄运金字塔”回调问题,可以尝试使用Promise。

参考:

答案 1 :(得分:1)

模式:

promise( executes async fcn and passes result to 'then')
          .then( myFcn(asynResult){use result})
          .then(...

是不可能的。 async函数只是立即返回,结果是未定义的,正如您所知道的那样。您无法从异步fcn

返回值

从异步调用中获取结果的经典设计是通过回调来实现的,这似乎是错综复杂的,如果你有嵌套的回调,可能会匆忙变得可怕。

承诺是针对这个问题而开发的。 Promise允许您编写类似于以下PSEUDO代码的代码

,从而部分解决了这个问题
result = wait for asyncFunction(...)

虽然不理想,但这允许您编写一种顺序异步代码。如果您还没有,我建议您花一些时间与Promises合作。

javascript社区仍然希望JS的未来版本允许以下内容:

if(item.firstname.toLowerCase().indexOf($scope.searchBuddy.toLowerCase())!= -1) {
      return true;

但它似乎还没有出现。