您花费了太多时间等待来自不同来源的 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
. Promise.props
接受一个对象并等待其所有属性解析(如果它们是Promise)。
请记住 - 生成器和Promise混合搭配得非常好,您只需产生Promise:
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
});
});
这是人们第一次使用生成器时常犯的错误。
克里斯·科瓦尔 (Kris Kowal) 无耻地从 Q-Connection 中获取了 ascii 艺术