放缓由于非并行异步发电机的承诺等待 [英] Slowdown due to non-parallel awaiting of promises in async generators

查看:143
本文介绍了放缓由于非并行异步发电机的承诺等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写使用发电机和蓝鸟code和我有以下内容:

I'm writing code using generators and Bluebird and I have the following:

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,这不是并行。我怎样才能提高我的应用程序的性能?

However, this is kind of slow, I feel like my application is waiting too much for I/O and it's not in parallel. How can I improve the performance of my application?

总响应时间为800 countryFor + 400 getCommentDataFor + 600 验证因此,在总1800ms这是很多。

The total response time is 800 for countryFor + 400 for getCommentDataFor + 600 for authenticate so in total 1800ms which is a lot.

推荐答案

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

You are spending too much time waiting for I/O from different sources.

在正常承诺code,你会使用 Promise.all 对于这一点,但是 - 人必须写code,它等待请求的倾向搭配发电机使用。您code执行以下操作:

In normal promise code, you'd use Promise.all for this, however - people have a tendency to write code that waits for requests with generators. Your code does the following:

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

相反,它应该做的事:

Instead, it should be doing:

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

简单地说,所有的I / O应该在这里并行完成。

Simply put, all your I/O should be done in parallel here.

要解决这个问题,我会使用<一个href=\"https://github.com/petkaantonov/bluebird/blob/master/API.md#props---promise\"><$c$c>Promise.props. Promise.props 花费其所有属性来解析对象和等待(如果他们的承诺)。

To fix this, I'd use Promise.props. Promise.props takes an objects and waits for all its properties to resolve (if they are promises).

记住 - 发电机和承诺混搭的真正的很好,你只需得到承诺:

Remember - generators and promises mix and match really well, you simply yield 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
    });
});

这是一个很常见的错误的人使用生成的第一次的时候做。

This is a very common mistake people make when using generators for the first time.

ASCII艺术由克里斯·科瓦尔从Q-连接无耻地采取

这篇关于放缓由于非并行异步发电机的承诺等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆