javascript – 由于异步生成器中的非并行等待承诺而导致速度下降

我正在使用生成器和Bluebird编写代码,我有以下内容:

var async = Promise.coroutine;
function Client(request){
    this.request = request;
}


Client.prototype.fetchCommentData = async(function* (user){
    var country = yield countryService.countryFor(user.ip);
    var data = yield api.getCommentDataFor(user.id);
    var notBanned = yield authServer.authenticate(user.id);
    if (!notBanned) throw new AuthenticationError(user.id);
    return {
        country: country,
        comments: data,
        notBanned: true
    };
});

但是,这有点慢,我觉得我的应用程序等待I / O太多而且它不是并行的.如何提高应用程序的性能?

对于countryFor 400,总响应时间为800,对于getCommentData为600,对于身份验证,因此总共1800毫秒,这是很多.

解决方法:

您花费了太多时间等待来自不同来源的I / O.

在普通的promise代码中,你可以使用Promise.all,但是 – 人们倾向于编写等待带有生成器的请求的代码.您的代码执行以下操作:

<-client     service->
countryFor..
           ''--..
              ''--..
                 ''--.. country server sends response
               ..--''
          ..--''
     ..--''
getCommentDataFor
     ''--..
           ''--..
               ''--..
                     ''--.. comment service returns response
                ..--''
          ..--''
      ..--''
authenticate
       ''--..
            ''--..
                  ''--.. authentication service returns
             ..--''
       ..--''
 ..--''
 Generator done.

相反,它应该做:

<-client     service->
countryFor..
commentsFor..''--..
authenticate..''--..''--..
                 ''--..''--..''--.. country server sends response
                        ''--..--''..  comment service returns response
                   ..--''..--''..     authentication service returns response
          ..--''..--''..
 ..--''..--''..--''
 ..--''..--''
 ..--''
 Generator done

简而言之,所有I / O都应该在这里并行完成.

为了解决这个问题,我使用Promise.props.Devise.props获取一个对象并等待其所有属性解析(如果它们是promises).

记住 – 生成器和承诺混合搭配得很好,你只需要产生承诺:

Client.prototype.fetchCommentData = async(function* (user){
    var country = countryService.countryFor(user.ip);
    var data = api.getCommentDataFor(user.id);
    var notBanned = authServer.authenticate(user.id).then(function(val){
          if(!val) throw new AuthenticationError(user.id);
    });
    return Promise.props({ // wait for all promises to resolve
        country : country,
        comments : data,
        notBanned: notBanned
    });
});

这是人们第一次使用发电机时常犯的错误.

 ascii艺术无耻地从K-Kowal的Q-Connection中获取

上一篇:javascript – 在本机ES6承诺中,Bluebird Promise.IIally的等价物是什么?


下一篇:javascript – 如何使用Node中的Promises一次执行并行异步多个请求