如何启用 async.mapLimit 以使用 TypeScript async / await

Jac*_*phy 2 async-await async.js typescript

是否可以使用Async NPM 模块在 TypeScript 2.2x 中使用async/ await

目标: 创建一个网络爬虫,使用异步的mapLimit 函数启动 10 个并行 HTTP 请求。

包装的 HTTP 函数的示例如下:

async callUniRest(url: string): Promise<number> {
  return new Promise<number>(resolve => {
    unirest.get(url)
      .end((response: any) => {
          resolve(cheerio.load(response.body);
      });
    });
}
Run Code Online (Sandbox Code Playgroud)

问题:

当我运行时:

const myList: string[] = ['http...', 'http...', 'http...', 'http...']
async.mapLimit(myList, 10, callUniRest, function(err: any, results: any {
  console.log(results);
})
Run Code Online (Sandbox Code Playgroud)

只有在第一个元素完成后才会调用回调。

问题: 如何启用async.mapLimit多个呼叫?

Ian*_*dge 5

是否可以使用“async”npm 模块在 Typescript 中使用 async/await

是的。

我发现这mapLimit只是为第一组调用迭代器。这是因为我是从 TypeScript 转译过来的。如果我将原生 async/await 与 JS 一起使用,那么它就起作用了。这是因为,引用自AsyncFunction异步文档

由于 JavaScript 的限制,我们只能检测原生异步函数,而不能检测转译的实现。

因此,如果您使用asyncifyasync 库包装迭代器,那么您可以从迭代器内部返回而不使用回调:

如果您通过转译器(例如 Babel)使用 async 函数,您仍然必须使用 asyncify 包装该函数,因为 async 函数将被编译为一个返回 promise 的普通函数。

这是一个有点人为的 TypeScript 示例,它演示了如何执行此操作。注意:如果您删除asyncify呼叫,它将不起作用:

import { asyncify, mapLimit } from "async";

const listOfThings = "abcdefghijklmnopqrstuvwxyz".split("");

const convertToUppercase = async () =>
  await mapLimit<string, string[]>(
    listOfThings,
    5,
    asyncify(async letter => letter.toUpperCase())
  );

const init = async () => {
  const uppered = await convertToUppercase();

  console.log("done", uppered);
};

init();
Run Code Online (Sandbox Code Playgroud)