这里我有4个函数返回promises。如果你运行hello并将每个传递给下一个.then
,你会得到一个长字符串。
var hello = function(str){
return Promise.resolve(str+ "hello")
}
var world = function(str){
return Promise.resolve(str+ "world")
}
var foo = function(str){
return Promise.resolve(str+ "foo")
}
var bar = function(str){
return Promise.resolve(str+ "bar")
}
// hello("alpha").then(world).then(foo).then(bar).then(console.log)
// => alphahelloworldfoobar
我希望能够将函数的平面数组传递给函数,并返回一个将它们全部嵌套的函数。
var arr = wrapThen([
hello,
world,
foo,
bar
])
arr("alpha").then(console.log)
这可能吗?蓝鸟是否提供此服务?
这就是我一起攻击的地方:
function wrapThen(arr){
var headPromise = arr.shift()
return function(){
var args = _.values(arguments)
var init = headPromise(args)
var values = []
return Promise.each(arr, function(item){
init = init.then(item)
return init.then(function(value){
values.push(value)
return value
})
}).then(function(){
return _.last(values)
})
}
}
答案 0 :(得分:2)
当然,对于蓝鸟来说这很容易,reduce
,这基本上是reduce
所做的事情(总结果):
let result = Promise.reduce([hello, world, foo, bar], function(result, action){
return action(result);
}, "alpha");
在ES2015表示法中,这变得更加冗长:
let {reduce} = Promise;
let result = reduce(arr, (result, action) => action(result), "alpha");
var hello = function(str){
return Promise.resolve(str+ "hello");
};
var world = function(str){
return Promise.resolve(str+ "world");
};
var foo = function(str){
return Promise.resolve(str+ "foo");
};
var bar = function(str){
return Promise.resolve(str+ "bar");
};
Promise.reduce([hello, world, foo, bar], function(result, action){
return action(result);
}, "alpha").then(function(endResult){
console.log(endResult);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>
答案 1 :(得分:0)
不确定您是否希望所有函数都获得相同的参数alpha
或仍然作为序列传递,因此我同时编写两者,只需使用.reduce
和.map
即可实现这两种方式。
var hello = function(str){
return Promise.resolve(str+ "hello");
};
var world = function(str){
return Promise.resolve(str+ "world");
};
var foo = function(str){
return Promise.resolve(str+ "foo");
};
var bar = function(str){
return Promise.resolve(str+ "bar");
};
// Wrap all functions in list, all give them the same value.
var wrapToArray = function(list) {
return function(result) {
var allP = list.map(function(item) {
return item(result);
});
return Promise.all(allP);
};
};
// Wraps all, and resolve them by array's sequence.
var wrapToSequence = function(list) {
return function(result) {
// Create a promise that resolved with result first.
var promise = Promise.resolve(result);
// Use reduce to chain the functions.
promise = list.reduce(function(prev, item) {
return prev.then(item);
}, promise);
return promise;
};
};
var arr = wrapToArray([hello, world, foo, bar]);
var arr2 = wrapToSequence([hello, world, foo, bar]);
arr("alpha").then(console.log.bind(console));
arr2("alpha").then(console.log.bind(console));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>
Bluebird还提供.reduce,.map以便更轻松地创建,以避免答案变得更长,演示在jsfiddle上。
var wrapToSequence = function(list) {
return function(result) {
return Promise.reduce(list, function(result, fn) {
return fn(result);
}, result);
};
};
var wrapToArray = function(list) {
return function(result) {
return Promise.map(list, function(fn) {
return fn(result);
});
};
};
答案 2 :(得分:0)
以下是使用Ramda
如何执行此操作的示例。
var R = require("ramda")
var hello = function(str){
return Promise.resolve(str+ "hello")
}
var world = function(str){
return Promise.resolve(str+ "world")
}
var foo = function(str){
return Promise.resolve(str+ "foo")
}
var bar = function(str){
return Promise.resolve(str+ "bar")
}
var result = R.pipeP(hello, world, foo, bar)
result("alpha").then(console.log) // logs -> "alphahelloworldfoobar"
result("alpha") // promise -> "alphahelloworldfoobar"