[英]Create asynchronous waterfall from objects
Say I have an array of objects which have asynchronous methods: 说我有一个具有异步方法的对象数组:
[
{
partOne: function(input) {
// Do something async
},
partTwo: function(result) {
// Do something w/ result of partOne
}
},
{
partOne: function(resultOfPrevious) {
// Do something async
},
partTwo: function(result) {
// Do something w/ result of partOne
}
},
{
partOne: function(resultOfPrevious) {
// Do something async
},
partTwo: function(result) {
// Do something w/ result of partOne
}
}
]
I want to execute partOne of the first object with my input, pass the result (async) to the partTwo callback, then pass the result of partTwo as input to partOne of the next object and so on. 我想用输入执行第一个对象的partOne,将结果(异步)传递给partTwo回调,然后将partTwo的结果作为输入传递给下一个对象的partOne,依此类推。 The array may be of one or more objects. 该阵列可以是一个或多个对象。 I'm wondering what the best pattern to execute this kind of code is? 我想知道执行这种代码的最佳模式是什么?
It is somewhat similar to the waterfall method of async.js: https://caolan.github.io/async/docs.html#waterfall , but I wonder how I can do this without a library and possibly with cleaner code? 它有点类似于async.js的瀑布方法: https ://caolan.github.io/async/docs.html#waterfall,但我想知道如何在没有库且可能没有更干净的代码的情况下做到这一点?
Not sure if async/await might help here? 不确定async / await是否对您有所帮助?
Another option without collecting every callback to an array, using async/await
: 另一种选择是使用async/await
而不将每个回调收集到数组中:
async function processWaterfallObject (data, input) {
let result = input
for (let entry of data) {
result = await entry.partOne(result)
result = await entry.partTwo(result)
}
return result
}
This assumes that functions in your data
array are either async
or return a Promise
. 假定data
数组中的函数要么async
要么返回Promise
。
async/await
is currently supported by every major browser and is available in node
since 7.6.0
. 每个主要浏览器当前都支持async/await
,并且从7.6.0
开始在node
7.6.0
。
Here is a simple function to invoke each asynchronous function in a stack 这是调用堆栈中每个异步函数的简单函数
function drain(stack, initialArg) {
stack.reduce(function (sectArg, section) {
return Object.keys(section).reduce(async function (arg, key) {
return await section[key].call(null,arg)
}, sectArg)
}, initialArg)
}
To use it ensure that each function in you stack returns a value 要使用它,请确保堆栈中的每个函数都返回一个值
var stack = [
{
partOne: function(input) {
// Do something async
console.log('section one partOne', input)
return 'section one partOne output'
},
partTwo: function(result) {
// Do something w/ result of partOne
console.log('section one partTwo', result)
return 'section one partTwo output'
}
},
{
partOne: function(resultOfPrevious) {
// Do something async
console.log('section two partOne', resultOfPrevious)
return 'section two partOne output'
},
partTwo: function(result) {
// Do something w/ result of partOne
console.log('section two partTwo', result)
return 'section two partTwo output'
}
},
{
partOne: function(resultOfPrevious) {
// Do something async
console.log('section three partOne', resultOfPrevious)
return 'section three partOne output'
},
partTwo: function(result) {
// Do something w/ result of partOne
console.log('section three partTwo', result)
return 'section three partTwo output'
}
}
]
So that you can invoke the stack like 这样您就可以像
drain(stack, 'initialArg')
See this jsfiddle: https://jsfiddle.net/kqj0rror/ 看到这个jsfiddle: https ://jsfiddle.net/kqj0rror/
Assuming your array of objects given in the original question is under a variable called waterfall 假设原始问题中给定的对象数组在一个名为Waterfall的变量下
let collector = [];
for (waterfallObj of waterfall) {
let tempArr = Object.values(waterfallObj);//get the functions out of the object
for (waterfallFunc of tempArr) {
collector.push(waterfallFunc);
}
}
//now you have your functions in order in collector
function recursiveCallback(i) {
if (i>collector.length-1) {
return;//if there are no more to call then return
}
collector[i]().then(function(){
recursiveCallback(i+1);
});
}
If you want the next function to do something with the previous functions value then simply change the then to then(function(passedValue and then use that passedValue in the recursiveCallback call within it 如果您希望下一个函数对前一个函数的值做某事,则只需将then更改为then(function(passedValue,然后在其中的recursiveCallback调用中使用该passValue
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.