Javascript 从对象创建异步瀑布
假设我有一个具有异步方法的对象数组:Javascript 从对象创建异步瀑布,javascript,node.js,asynchronous,async-await,async.js,Javascript,Node.js,Asynchronous,Async Await,Async.js,假设我有一个具有异步方法的对象数组: [ { partOne: function(input) { // Do something async }, partTwo: function(result) { // Do something w/ result of partOne } }, { partOne: function(resultOfPrevious) { // Do something async
[
{
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
}
}
]
我想用输入执行第一个对象的partOne,将结果(异步)传递给partTwo回调,然后将partTwo的结果作为输入传递给下一个对象的partOne,依此类推。阵列可以是一个或多个对象。我想知道执行这种代码的最佳模式是什么
它有点类似于async.js:的瀑布方法,但我想知道,如果没有库,可能还有更干净的代码,我怎么能做到这一点
不确定async/await是否有帮助 假设原始问题中给出的对象数组位于名为瀑布的变量下
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);
});
}
如果您想让下一个函数使用前一个函数的值执行某些操作,那么只需将then改为then(函数)(passedValue,然后在其中的递归回调调用中使用该passedValue,假设原始问题中给出的对象数组位于名为瀑布的变量下
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);
});
}
如果希望下一个函数使用前一个函数值执行某些操作,则只需将then更改为then(函数)(passedValue,然后在其中的递归回调调用中使用该passedValue)另一个选项,而无需使用
async/wait
收集对数组的每个回调:
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
}
这假设数据
数组中的函数是异步
或返回承诺
async/await
当前受节点的支持,并且在节点中可用,因为7.6.0
使用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
}
这假设数据
数组中的函数是异步
或返回承诺
async/await
目前受节点的支持,并且在节点中可用,因为7.6.0
这里有一个简单的函数来调用堆栈中的每个异步函数
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)
}
要使用它,请确保堆栈中的每个函数都返回一个值
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'
}
}
]
这样您就可以像
drain(stack, 'initialArg')
请参阅此JSFIDLE:这里有一个简单的函数来调用堆栈中的每个异步函数
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)
}
要使用它,请确保堆栈中的每个函数都返回一个值
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'
}
}
]
这样您就可以像
drain(stack, 'initialArg')
查看此JSFIDLE:您没有pop
ping收集器
的任何位置,因此递归回调
函数将抛出,超过最大调用堆栈大小
。为什么我需要弹出?我在其中有一个返回语句,用于在所有收集器函数都处理得很糟糕的情况下,您将理顺了。我忽略了I>…
部分。您没有pop
ping收集器的任何位置,因此recursiveCallback
函数将在超出最大调用堆栈大小的情况下抛出。为什么我需要弹出呢?我在那里有一个return语句,用于所有收集器函数都已打开时处理得很糟糕,你完全正确。我忽略了I>部分。这并不能解释函数是异步的。太好了!我还注意到你在调用部分[key]
使用此
-我不确定这是否是一个好主意,它可能会导致代码中出现许多意想不到的错误。也许你应该使用null
来代替?我同意null
更合适。我会进行更新。谢谢你的提示。这并不能说明函数是异步的。太好了!我也注意到了d您正在呼叫ing部分[键]
使用这个
-我不确定这是不是一个好主意,它可能会导致代码中出现很多意想不到的错误。也许你应该使用null
来代替?我同意null
更合适。我会进行更新。谢谢你的提示。非常好,非常干净。非常好,非常干净。