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'] 
}) 

要容易理解得多。对?

+0

哎呀,对不起,我只是错误地理解了这个问题 – Octopitus