JS:获取异步函数内部函数参数和执行回调
问题描述:
我试着写一个返回的异步函数的所有结果的功能,并执行推到一个数组的回调和记录每一个异步函数的结果。JS:获取异步函数内部函数参数和执行回调
由于把所有的菜时,他们都做了服务员。 我不明白如何获得应该作为结果返回的子参数。任务,我不工作的解决方案的代码如下:
任务:
var dishOne = function(child) {
setTimeout(function() {
child('soup');
}, 1000);
};
var dishTwo = function(child) {
setTimeout(function() {
child('dessert');
}, 1500);
};
waiter([dishOne, dishTwo], function(results) {
console.log(results); // console output = ['soup', 'dessert']
});
我不工作的解决方案:
function child(arg) {
this.arr.push(arg)
}
function waiter(funcArray, doneAll) {
var result = {
arr: []
};
let i = 0;
const x = child.bind(result)
funcArray.forEach(function(f) {
f(x)
i++;
if(i == 2) {
doneAll(result.arr)
}
});
}
答
问题是这样的部分:
funcArray.forEach(function(f) {
f(x)
i++;
if(i == 2) {
doneAll(result.arr)
}
});
这是一个同步功能,所以当你检查if(i == 2)
时,你基本上检查,你已经调用了所有的同步功能,但他们还没有返回任何东西,所以你知道的是,这些功能已被调用,但result.arr
尚未填充。
您必须将doneAll(result.arr)
表达式移入child
回调函数中,然后它将由异步函数调用,因为它返回结果。
Simpliest解决方案,我能想到的是写你child
为
function child(arg) {
if (this.arr.push(arg) === this.allCount) this.doneAll(this.arr);
}
,并在您waiter
功能增强的结果对象
var result = {
arr: []
, allCount: funcArray.length
, doneAll: doneAll
};
这应工作,但有一个缺点 - 结果的位置不保持funcArray
的功能位置,结果的位置由异步函数的时间排序,干脆先解决将需要第一个结果等。如果这是一个问题,你也必须通过指数您child
功能存储导致在结果阵列珍贵的位置,然后通过arr.length
检查是行不通的,因为JS数组返回长度为最高指数+ 1,因此,如果您的最后一个funcArray
将首先完成,这将填补最后一个索引和result.arr
长度将等于this.allCount
,所以为了保持结果的顺序一样funcArray
,你将需要存储返回结果的数量另一个号码,增加与每一个新的结果,这个数字,这个数字比较allCount
。
,或者降低allCount像这样
function child(idx, arg) {
this.arr[idx] = arg;
if (--this.allCount === 0) this.doneAll(this.arr);
}
和修改waiter
功能
function waiter(funcArray, doneAll) {
const result = {
arr: []
, allCount: funcArray.length
, doneAll: doneAll
};
funcArray.forEach(function(f, i) {
f(child.bind(result, i));
});
}
答
为什么不Promise?
function dishOne() {
return new Promise(function(resolve, reject) {
setTimeout(function() { resolve('soup') }, 1000)
})
}
function dishTwo() {
return new Promise(function(resolve, reject) {
setTimeout(function() { resolve('dessert') }, 1500)
})
}
你waiter
功能:
function waiter(dishes, callback) {
return Promise.all(dishes).then(callback)
}
而且你可以使用它像这样
waiter([dishOne(), dishTwo()], function(results) {
// Invoked when all dishes are done
console.log(results) // ['soup', dessert']
})
要容易理解得多。对?
哎呀,对不起,我只是错误地理解了这个问题 – Octopitus