Promise写法问题
发布于 8 年前 作者 im-here 5150 次浏览 来自 问答

假如我有一个查询用户数据的需求,逻辑是这样的:先从缓存查,如果缓存里没有,再从数据库查,我用promise实现如下:

exports.getUserData=function(){
	return redis.getAsync().then(function(val){
		if(val)
			return db.findFromDB(sql).then(function(val){
				return val;
			});
		else return val;
	}).catch(function(error){
		//....
	});
}

我怎么感觉我这样的写法和多层callback没区别了,是我写法不对吗?

7 回复

你这写法不能说不对,但是可读性有点尴尬。。。可以这样组织逻辑

Promise.resolve()
.then(function(){
	return redis.getAsync();
})
.then(function(val){
	if(val) return db.findFromDB(sql);
	return val;
})
.then(function(val){
	//TODO: sth
})
.catch(function(err){
	//TODO: err
});

@lgyhitler 这样的话 上面的代码能封装成一个函数么? 我试了下 假如上面代码封装函数名为getUserData(),应该如何调用? 其实我要的就是上面的代码是一个函数,另外一个函数调用该函数,拿到该函数返回的值做输出!

你应该是没搞明白Promise得真正意图,整个流程都是异步的所以会出现层层callback,Promise相当于用一种封装的形式来代替callback,每个then都是异步的,但是每个then()返回的都是一个Promise对象,这样的话就允许实现类似链式调用的方式进行流程控制。你若是想将上面的封装成一个函数,那就调用它的方式还得是Promise。 比如上面的封装成 函数getUserData,那调用方式就是:

function Fn(){
	Promise.resolve()
			.then(function(){
				return getUserData();
			})
			.then(function(userData){
				//TODO: userData
			})
}

@lgyhitler 我这样封装了下,应该没问题吧? 测了下 ,运行正常!

function Fn(){
  return Promise.resolve()
  .then(function(){
	  return redis.getAsync();
  })
  .then(function(val){
	  if(val) return db.findFromDB(sql);
	  return val;
  });
}
//调用
Fn().then(function(val){
	//输出结果
}).catch(function(error){
	//处理错误
})

是的,没错

@imhered redis.getAsync() 是返回 Promise 么? 如果是的话, 我觉得其实就不需要再写一遍 Promise.resolve() 了. Fn 直接从 return redis.getAsync() 开始就行.

另外, 你的 if(val) 是不是写反了? 有缓存的时候去执行 sql ?

@Chunlin-Li 嗯,是的。代码已经改过了,直接从return redis.getAsync()开始的,if(val)这个确实是写反了,不过只是提问的时候写反了的

回到顶部