比如以下例子,如何在第二步的then中需要访问第一步的then获取到的数据库对象
db.find(condition).then(function(data){
return redis.connect(config);//返回Promise
).then(function(redisInstance){
//使用Redis实例操作数据库对象data
}).catch(function(err){
console.log(err);
});
个人想到的方法有两种:
//在链式调用外设置全局变量
let state={};
db.find(condition).then(function(data){
state.data=data;
return redis.connect(config);//返回Promise
).then(function(redisInstance){
redisInstance.save(state.data.id,state.data);
}).catch(function(err){
console.log(err);
});
//嵌入式的写法,将第二步嵌入第一步中
db.find(condition).then(function(data){
return redis.connect(config).then(function(redisInstance){
redisInstance.save(data.id,data);
});
).catch(function(err){
console.log(err);
});
//使用第三方的库co
co(function*(){
try{
let data=yield db.find(condition);
let redis=yield redis.connect(config);
yield redis.save(data.id,data);
}catch(err){
console.log(err);
}
});
除了这两种外,还有没有更好的写法?
更好的写法是用 async/await ....
async () => {
let data = await db.find(condition);
let redisInstance = await redis.connect(config);
redisInstance.save(data.id, data);
}
差不多就是这两种方法,具体到题主的情况,我建议用类似第二种的办法,但可以做一层抽象提升语义和易维护性
db.find(condition).then(saveToRedis).catch(function(err){
console.log(err);
});
function saveToRedis(data) {
return redis.connect(config).then(function(redisInstance){
redisInstance.save(data.id,data);
});
}
还有一种行为不太一样的方法是用Promise.when
Promise.when(db.find(condition), redis.connect(config)).then(function(data, redisInstance) {
redisInstance.save(data.id, data);
});
缺点是即使db.find失败,redis还是连接上了,和原本的行为不太一样