如何仅修改getNumList函数实现有序打印随机延迟数字?
问题与解决方案
现有如下JavaScript代码:
function getNum(value, callback){ setTimeout(()=> { callback(value) }, Math.random()*1000) } function getNumList(arr, callback){ //complete this function //use the given "getNum" function //(not allowed to use Math.sqrt function) //(not allowed to use setTimeout function) for(let i=0; i<arr.length;i++) getNum(arr[i],callback) } getNumList([1,3,2,4,6,5,7,9,8,10], (nums)=> console.log(nums)) //should print [1,3,2,4,6,5,7,9,8,10] in console要求仅修改
getNumList函数,在不修改getNum函数、不使用setTimeout和Math.sqrt的情况下,实现调用getNumList后按输入数组的顺序打印数字。原提问者认为递归或Promise方案似乎需要修改getNum函数,询问是否有可行的解决办法?
可行解决方案
核心思路是串行执行每个getNum调用,等前一个元素的回调触发后再处理下一个,就能保证顺序。不用改getNum,也不用禁用的API,用递归就能实现:
function getNumList(arr, callback) { // 内部递归函数,逐个处理数组元素 function processNext(index) { if (index >= arr.length) return; // 数组处理完就终止 // 调用当前元素的getNum,回调里触发下一个元素的处理 getNum(arr[index], (value) => { callback(value); processNext(index + 1); }); } // 从第一个元素开始启动处理 processNext(0); }
原理说明
- 内部的
processNext函数一次只处理数组中的一个元素,只有当前元素的异步回调执行完毕,才会递归处理下一个元素。 - 因为异步操作是按顺序触发的,所以输出的数字严格和输入数组的顺序一致。
- 完全满足要求:没修改
getNum,没使用setTimeout或Math.sqrt,仅修改了getNumList函数。
内容的提问来源于stack exchange,提问作者Guinea guinea
相关产品推荐
相关产品推荐

