在同步一个内部等待asynchronouscallback函数

我用mysql2-node模块使用Express JS来创build一个访问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

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

有没有反正我可以强制indexOfUserInVotingList等待查询完成并返回结果?

最重要的一点是,我不想把它变成asynchronous函数(虽然这种方法可行):

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

..因为我不想卡在callback内 ,就像:

 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... } } 

模式:

 result = asyncDoSomething(...);// returns value 

不可能。 asynchronous函数只是立即返回,结果不确定,就像你发现的那样。 你不能从asynchronousfcn返回一个值

从asynchronous调用获得结果的经典devise是callback,看起来很复杂,如果嵌套callback,可能会变得非常可怕。

承诺是为了这个问题而开发的。 承诺部分地解决了这个问题,允许你编写看起来像下面的PSEUDO代码的代码

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

虽然不理想,但这可以让你编写一个顺序的asynchronous代码。 如果你还没有,我鼓励你花一些时间与诺言。

JavaScript社区仍然希望JS的未来版本将允许像这样的东西:

 result = wait for asyncFunction(...) 

但似乎还没有出现。

由于node.js使用的是非阻塞的I / O模型,所以当涉及到I / O操作时,不可能在没有等待callback的情况下获取数据。

如果你有“厄运金字塔”的callback问题,你可以尝试使用Promise。

参考: