首页 > Promise的链式调用过程中如何传递状态?

Promise的链式调用过程中如何传递状态?

比如以下例子,如何在第二步的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还是连接上了,和原本的行为不太一样

【热门文章】
【热门文章】