提问人:kbl 提问时间:10/10/2023 最后编辑:Barmarkbl 更新时间:10/10/2023 访问量:46
异步 JS 中的嵌套回调
Nested callbacks in asynchronous JS
问:
我刚开始学习 Javascript 的异步特性,遇到了其他人所说的回调地狱。有人可以就以下处理嵌套回调的方法提供一些想法吗?这种方法是否可能存在问题或缺点。
比方说,我想异步随机生成一个数字。然后,通过函数修改生成的数字。
function delayedFunctionalites(wait, ...funcs) {
setTimeout(() => {
let randNum = Math.floor(Math.random() * 10);
console.log(`randNum is ${randNum}`);
let updatedRandNum = funcs.reduce((acc, func) => func(acc), randNum);
console.log(`updatedRandNum is ${updatedRandNum}`);
}, wait);
}
const addOne = (input) => input + 1;
const multBy2 = (input) => input * 2;
const addFive = (input) => input + 5;
delayedFunctionalites(2000, addOne, multBy2, addFive);
// Output: randNum is 8
// Output: updatedRandNum is 23
答:
1赞
nullromo
10/10/2023
#1
我认为您从评论中得到了一些很好的见解,但为了完整起见,这里有一些不同的方法可以进行承诺链接。
测试功能
此函数在延迟 1 秒后将数字加 4。这在下面的示例中使用。
const testFunction = async (input: number) => {
return new Promise<number>((resolve) => {
setTimeout(() => {
resolve(input + 4);
}, 1000);
});
};
一遍又一遍地打电话.then()
这是您通常将承诺链接在一起的方式。每一个都紧随其后,并使用前一个的结果。
const callbackChaining = async () => {
const value = 5;
console.log('Value is', value);
const result = await testFunction(value)
.then(async (result) => {
console.log('Value is', result);
return testFunction(result);
})
.then(async (result) => {
console.log('Value is', result);
return testFunction(result);
})
.then(async (result) => {
console.log('Value is', result);
return testFunction(result);
});
console.log('Result is', result);
};
将循环与for
await
您可以使用普通循环来获取每个操作的结果,然后对其调用下一个操作。await
请注意,有一个 eslint 规则警告不要在循环中使用 await
,因此您需要研究一下它是否与您的情况相关。
const forLoop = async () => {
let value = 5;
const operations = [testFunction, testFunction, testFunction, testFunction];
for (const operation of operations) {
console.log('Value is', value);
// eslint-disable-next-line no-await-in-loop
value = await operation(value);
}
console.log('Result is', value);
};
用Array.prototype.reduce()
您在问题中使用了。这里有一个类似的使用方法,可以将承诺列表的结果链接在一起。reduce
const arrayReduce = async () => {
const value = 5;
const operations = [testFunction, testFunction, testFunction, testFunction];
const result = await operations.reduce(async (result, operation) => {
return result.then(async (value) => {
console.log('Value is', value);
return operation(value);
});
}, Promise.resolve(value));
console.log('Result is', result);
};
评论
funcs.reduce((acc, func) => func(acc), randNum);