我需要在我的函数中使用跟随逻辑:
例如,在java中,它会是这样的:
try {
User user = userService.findByFacebookAccount(id);
if(user != null) {
done(user);
} else {
user = userService.findByEmail(email);
if(user != null) {
user.setFacebookAccount(id);
if(userService.update(user)) {
done(user); // Update with success
} else {
throws new Exception();
}
} else {
user = userService.createByFacebookAccount(name, email, facebook_id);
if(user != null) {
done(user);
} else {
throws new Exception();
}
}
}
} catch(Exception e) {
done(e);
}
我如何组织与Promises有关的事情? 我使用蓝鸟承诺如下:
function(accessToken, refreshToken, profile, done) {
var profileInfos = profile._json;
userService.findByFacebookAccount(profileInfos.id).then(function(user) {
done(null, user);
}).error(function(e) {
return userService.findByEmail(profileInfos.email);
}).then(function(user) {
user.set('facebook_account', profileInfos.id);
return userService.update(user, ['facebook_account']);
}).then(function(user) {
done(null, user);
}).error(function(e) {
return userService.createByFacebookAccount(profileInfos.name, profileInfos.gender, profileInfos.username, profileInfos.email, profileInfos.id);
}).then(function(user) {
done(null, user);
}).catch(function(e) {
done(null);
});
}
我认为这是错误的,因为当"返回userService.update(用户,[' facebook_account']);"被拒绝我需要捕获错误并返回错误并且不创建用户。
从同步逻辑转换为承诺的最佳方法是什么?
答案 0 :(得分:1)
不要混合使用promises和callback,除非你想制作一个回调api,但想在内部使用promises(在这种情况下使用.nodeify
)。也不要吞下错误并强迫用户检查返回值。
function doIt(accessToken, refreshToken, profile, done) {
var profileInfos = profile._json;
return userService.findByFacebookAccount(profileInfos.id).then(function(user) {
if (user != null) {
return user;
}
return userService.findByEmail(profileInfos.email).then(function(user) {
if (user != null) {
user.setFacebookAccount(id))
return userService.update(user).then(function(updated) {
// userService should actually just throw the error in the first place and not
// swallow it and return false, which is making code much uglier than it needs to be here
if (!updated) throw new Error();
return user;
});
} else {
return userService.createByFacebookAccount(name, email, facebook_id).then(function(user) {
if (user != null) return user;
throw new Error();
})
}
})
}).nodeify(done);
}
用法是:
doIt(...)
.then(function(user) {
})
.catch(function(error){
});
由于我们使用了.nodeify()
,因此也支持回调接口:
doIt(..., function(err, user) {
});
如果服务使用异常而不是在出现错误时返回null / false,则可能会稍微清晰一些:
function doIt(accessToken, refreshToken, profile, done) {
var profileInfos = profile._json;
return userService.findByFacebookAccount(profileInfos.id).then(function(user) {
if (user != null) {
return user;
}
return userService.findByEmail(profileInfos.email).then(function(user) {
if (user != null) {
user.setFacebookAccount(id))
return userService.update(user).thenReturn(user);
} else {
return userService.createByFacebookAccount(name, email, facebook_id)
}
})
}).nodeify(done);
}