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

假如我有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 回复

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

@manxisu 卧槽,我2b了。怎么就没想到呢。。。

看了下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

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

我是用的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];
	// 继续
})

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

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

A().bind({}).then(function (a) {
  this.a = a
  return b
}).then(function (b) {
  return b + this.a
})

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

@imhered 可以的,我的写法跟 @SinalVee的等价,只不过分开了。 From Noder

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

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);
  });
});

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

return A().then(function(dataA){
	return Promise.all([
	  dataA,
	  B(dataA.id)
	]);
}).spread(function(dataA, dataB){
	return C(dataA, dataB);
})

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

@klesh 嗯 多谢!

回到顶部