在同步一个内部等待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。
参考:
- 为什么node.js是asynchronous的?
- 如何使用可以启动/停止的recursion函数编写应用程序
- Nodejs的callback机制 – 哪个线程处理callback?
- 使用async.waterfall
- 使用asynchronousdb编程来sorting动作
- AWS Lambda函数如何更新DynamoDB表中的所有logging?
- testing一个Node.js函数,它的返回值可以根据执行asynchronous操作的时间而改变
- 在Node.jsdevise模式中释放zalgo为什么asynchronouspath一致?
- 在globals.js中注释asynchronous不会影响其在服务中的使用