CNode

问一个Promise写法

问答
Iim-here发布于10 年前最后回复10 年前15 回复5736 浏览0 收藏

假如我有A,B,C 3个函数,处理流程如下

return A().then(function(dataA){
	//这里通过A函数拿到的dataA,去做一些操作,假如是调B函数查数据
	return B(dataA.id);
}).then(function(dataB){
	//假如我这里要将A函数拿到的dataA里的name和B函数拿到dataB里的id去调C函数
	//即 C(dataA.name,dataB.id),这里应该怎么弄,我能想到的就是一层层嵌套写了,但这样的话,和callback区别了	
})

实际的业务中可能不止3个函数,可能会更多,而且后面的函数可能会用到前面函数的结果,逻辑上应该怎么写呢?

查看回复

回复 (15)

M
manxisuo#1·10 年前

我能想到是:在外层作用域定义相应的变量,用于保存前面的数据,从而共享给后面的过程使用。 From Noder

M
manxisuo#3·10 年前

看了下Promise的API,可以用Promise.all()方法:

var p1 = A(); var p2 = p1.then(function (dataA) { return B(dataA.id); }); Promise.all([p1, p2]).then(function (values) { // values就是dataA和dataB组成的数组。 var dataA = values[0]; var dataB = values[1]; });

From Noder

I
im-here#4·10 年前
引用 manxisuo看了下Promise的API,可以用Promise.all()方法: var p1 = A(); var p2 = p1.then(function (dataA) { return B(da...

@manxisuo 我这种情况all不行的,因为我要先通过A查询出结果,然后拿A的结果作为B的参数,依次类推。不过你说在最外面定义相应变量这个倒是可行

S
SinalVee#5·10 年前

我是用的Promise.all()

return A().then(function(dataA){
	return B(dataA.id);
	return Promise.all([
	  Promise.resolve(dataA),
	  B(dataA.id)
	]);
}).then(function(results){
	var dataA = results[0];
	var dataB = results[1];
	// 继续
})
I
im-here#6·10 年前
引用 SinalVee我是用的Promise.all()

@SinalVee 哦,这样倒也可以,这样实际上是把A函数的结果,做了一个返回。

Y
Yu1989#7·10 年前

在外面放一个变量吧. 如果用的是Bluebird, 可以用Promise.bind.

A().bind({}).then(function (a) {
  this.a = a
  return b
}).then(function (b) {
  return b + this.a
})
I
im-here#8·10 年前
引用 Yu1989在外面放一个变量吧. 如果用的是Bluebird, 可以用Promise.bind.

@Yu1989 嗯,用的是bluebird。 我看看 bind用法

I
im-here#10·10 年前
引用 manxisuo@imhered 可以的,我的写法跟 @SinalVee的等价,只不过分开了。 From Noder

@manxisuo 哦,确实是可以,刚开始没注意看你的代码,谢谢!

K
klesh#12·10 年前
return A().then(a => B(a).then(b => C(a, b)));

并不是一定不能嵌套,而是不要过深嵌套,关键在于可读性。你这种情形反而是嵌套一下更容易理解,一眼看过去就能知道 c 依赖于 a,b, b 依赖于 a。

return A().then(a => {
  return B(a).then(b => {
    return C(a, b);
  });
});
W
wangning0#13·10 年前

mark

K
klesh#14·10 年前
引用 SinalVee我是用的Promise.all()

@SinalVee 思路不错,代码好像写错了吧?

return A().then(function(dataA){
	return Promise.all([
	  dataA,
	  B(dataA.id)
	]);
}).spread(function(dataA, dataB){
	return C(dataA, dataB);
})
S
SinalVee#15·10 年前
引用 klesh@SinalVee 思路不错,代码好像写错了吧?

@klesh 嗯,复制粘贴的时候没删好 From Noder

参与回复
登录后即可参与回复。登录