如何循环等待,直到 API 中的一系列调用在 Javascript 中完成

How to wait in loop till the series of API calls one inside another is completed in Javascript

我陷入了打字稿的困境。

我有一个 forEach 循环,其中执行了一个 API 调用方法 methodOne();在这个方法中,另一个 API 对 methodTwo() 的调用被 [顺序] 执行。

现在我的要求是 forEach 循环应该等到 API 调用都被执行,然后 forEach 应该进行下一次迭代。

代码流如下所示:

list.forEach(item => {
    methodOne(item);
})

methodOne(){
    methodTwo();
}

methodTwo(){
    //some code..
}

注意:我在API调用

中没有使用任何async, await, Promise or Observables

一个!像那样!这个?

只需将一堆异步回调提供给promiseChain,它就会按顺序执行它们。

function methodTwo() {
  // some code..
  return Promise.resolve(); // <= Or any async code
}

function methodOne(item: number) {
  return methodTwo().then(result => {
    // some code..
    return { item, result };
  });
}

async function promiseChain<T>(callbacks: (() => Promise<T>)[]) {
  var output: T[] = [];
  for (const callback of callbacks) {
    const result = await callback();
    output.push(result);
  }
  return output;
}

const list = [1, 2, 3, 4];
promiseChain(list.map(item => () => methodOne(item)))
  .then(responses => {
    // DO STUFF HERE
    const first_response = responses[0]; // Result of `methodOne(list[0])`
    const second_response = responses[1]; // Result of `methodOne(list[1])`
  });

请注意,异步函数(.then()async/await)在 forEach 中不起作用 ALSO .then() 方法在 forEachfor 循环中都不起作用。

要运行循环内的异步函数,您需要在for循环或Recursion Function.

内使用async/await方法

在下面的示例中,我们将在 for 循环中使用 async/await 方法。

const list = ['firstItem', 'secondeItem', 'lastItem'];

// First method
// use `i` parameter to check in which index the method was called
function methodOne(i: string): Promise<void> {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(`Make the first API call at index ${i}`);
            resolve();
        }, 1000);
    });
}


// Second method
// use `i` parameter to check in which index the method was called
function methodTwo(i: string): Promise<void> {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(`Make the second API call at index ${i}`);
            resolve();
        }, 1000);
    });
}

// run both methods sequentially inside a `for` loop
async function runMethodOneAndMethodTwoInsideLoop (): Promise<void> {
    for (let i in list) {
        await methodOne(i);
        await methodTwo(i);
    }
}

runMethodOneAndMethodTwoInsideLoop();

要在 methodOne 中调用 methodTwo(我不推荐这样做),您可以使用以下示例。

const list = ['firstItem', 'secondeItem', 'lastItem'];

// First method
// use `i` parameter to check in which index the method was called
function methodOne(i: string): Promise<void> {
    return new Promise((resolve) => {
        setTimeout(async () => {
            console.log(`Make the first API call at index ${i}`);
            await methodTwo(i);
            resolve();
        }, 1000);
    });
}


// Second method
// use `i` parameter to check in which index the method was called
function methodTwo(i: string): Promise<void> {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(`Make the second API call at index ${i}`);
            resolve();
        }, 1000);
    });
}

// run only `methodOne` inside a `for` loop since `methodTwo` will be called inside `methodOne`
async function runMethodOneInsideLoop(): Promise<void> {
    for (let i in list) {
        await methodOne(i);
    }
}

runMethodOneInsideLoop();

要了解有关异步函数以及如何在循环内使用它们的更多信息,请查看我创建的 this gist