1

有没有办法不使用 await inside loop 来执行以下代码?

const redirects = ['redirectId1'];

for (let i = 0; i < redirects.length; i++) {
  const promiseResult = await anAsyncFunction(redirects[i]);
  
  if (promiseResult.redirects) {
    redirects.forEach(newRedirect => {
      if (!redirects.includes(newRedirect)) redirects.push(newRedirect);
    });
  }
}

我试过使用地图

const redirects = ['redirectId1'];

const promiseArr = redirects.map(async redirect => {
  const promiseResult = await anAsyncFunction(redirect);

  if (promiseResult.redirects) {
    redirects.forEach(newRedirect => {
      if (!redirects.includes(newRedirect)) redirects.push(newRedirect);
    });
  }
});

await Promise.all(promiseArr);

但这样做时,代码会在newRedirect被推送到重定向数组之前进一步执行,因此不会调用anAsyncFunction新的附加值。

我想知道是否有任何可能的方法来实现这一目标?

4

2 回答 2

1

如果想法是尽快发送每个请求,而无需等待更早的请求首先解决,您可以使用递归异步函数,该函数在结果包含重定向时调用自身:

const recurse = (redirects) => Promise.all(
  redirects.map(r => anAsyncFunction(r)
    .then(({ redirects }) => {
      if (redirects) {
        return recurse(redirects);
      }
    })
  )
);
// pass in the initial array:
await recurse(redirects);

如果您以后还需要使用填充的外部redirects数组,那么:

const recurse = (redirects) => Promise.all(
  redirects.map(r => anAsyncFunction(r)
    .then(({ redirects }) => {
      return redirects
        ? recurse(redirects).then(res => [redirects, res])
        : [];
    })
  )
);
// pass in the initial array:
const allRedirects = [initialRedirects, await recurse(initialRedirects)].flat(Infinity);
于 2021-04-14T04:56:17.083 回答
0

如果您有兴趣每个重定向批次将是并行的,并且只要存在就不断要求更多重定向,您可以按以下方式实现:

const handleRedirects = async (_redirects) => {
  const newRedirects = [];
  await Promise.all(
    _redirects.map(async (redirect) => {
      const promiseResult = await anAsyncFunction(redirect);

      if (promiseResult.redirects) {
        promiseResult.redirects.forEach((newRedirect) => {
          if (!_redirects.includes(newRedirect)) newRedirects.push(newRedirect);
        });
      }
    })
  );
  return newRedirects;
};


const run = async () => {
  const redirects = ['redirectId1'];
  let newRedirects = [ ...redirects ];
  do {
    newRedirects = await handleRedirects(newRedirects);
    redirects.push(...newRedirects);
  } while (newRedirects.length)
}
于 2021-04-18T12:30:38.253 回答