return 承诺的嵌套函数数组
Nest array of functions that return promises
这里我有 4 个 return 承诺的功能。如果你 运行 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
我希望能够将函数的平面数组传递给一个函数并得到 return 一个将它们全部嵌套的函数。
var arr = wrapThen([
hello,
world,
foo,
bar
])
arr("alpha").then(console.log)
这可能吗? bluebird 提供这个吗?
这是我一起破解的:
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)
})
}
}
不确定您是否希望所有函数都获得相同的参数 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 to create it easier, to avoid the answer become longer, demo is on 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);
});
};
};
当然,使用 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>
这是一个如何使用 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"
这里我有 4 个 return 承诺的功能。如果你 运行 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
我希望能够将函数的平面数组传递给一个函数并得到 return 一个将它们全部嵌套的函数。
var arr = wrapThen([
hello,
world,
foo,
bar
])
arr("alpha").then(console.log)
这可能吗? bluebird 提供这个吗?
这是我一起破解的:
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)
})
}
}
不确定您是否希望所有函数都获得相同的参数 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 to create it easier, to avoid the answer become longer, demo is on 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);
});
};
};
当然,使用 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>
这是一个如何使用 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"