异步 JS 中的嵌套回调

问题描述 投票:0回答:1

我刚刚开始学习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

javascript callback nested
1个回答
0
投票

我认为您从评论中获得了一些很好的见解,但为了完整起见,这里有一些您可以进行承诺链的不同方法。

测试功能

此函数在 1 秒延迟后将数字加 4。这在下面的示例中使用。

const testFunction = async (input: number) => {
    return new Promise<number>((resolve) => {
        setTimeout(() => {
            resolve(input + 4);
        }, 1000);
    });
};

打电话
.then()
一遍又一遍

这是通常将 Promise 链接在一起的方式。每个都在下一个之后,并使用前一个的结果。

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);
};
© www.soinside.com 2019 - 2024. All rights reserved.