Slowdown due to non-parallel awaiting of promises in async generators

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

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

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

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 art shamelessly taken from Q-Connection by Kris Kowal

Leave a Comment