2016-11-23 32 views
1

异步回调函数,我使用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,它需要该用户标识的索引才能工作:

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:未定义

我了解到,在indexOfUserInVotingListreturn行动之前mysql-query运行立即执行并更新值。

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

最重要的一点是,我不想把它转换成异步功能(尽管这种方法是有效的):

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

..because我不想陷入内部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... 
      } 
} 
+1

不可能。如果它是异步的,它保持异步。您不必使用回调,但可以使用承诺。 – Bergi

回答

1

图案:

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

是不可能的。正如你所发现的那样,异步函数只是立即返回而结果不确定。你不能从一个异步函数返回一个值从一个异步调用获得结果的经典设计是一个回调,它看起来很复杂,如果你有嵌套的回调函数,可能会很急。

承诺是为这个问题而开发的。通过允许你写的代码看起来像下面的伪代码

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

虽然不是很理想的承诺部分地解决这个问题,这可以让你写的顺序异步代码的形式。如果你还没有,我鼓励你花一些时间与诺言。

JavaScript社区仍然希望JS的未来版本将允许类似:

result = wait for asyncFunction(...) 

但它似乎并没有在地平线上还没有。

+0

['async' /'await'](http://tc39.github.io/ecmascript-asyncawait/)不在地平线上,是的。因为它已经在我们的引擎中,并且只等待进入下一个规格修订!当然,这仍然不会使异步函数同步,它只是简化了编写异步代码。 – Bergi