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

时间:2017-08-08 15:46:17

标签: typescript async-await async.js

是否可以使用' async' npm模块在Typescript 2.2x中使用async / await

目标: 我想创建一个web scraper,它使用以下方法旋转10个并行的http请求:

HEX()

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

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

问题:

当我打电话

const myList: string[] = ['http...', 'http...', 'http...', 'http...']
async.mapLimit(myList, 10, callUniRest, function(err: any, results: any {
  console.log(results);
}) 
  • 仅在第一个元素完成
  • 后调用回调

问题: 如何启用async.mapLimit以处理多个调用。

2 个答案:

答案 0 :(得分:2)

  

是否可以使用'async'npm模块与Typescript中的async / await一起使用

是的

我发现mapLimit只是为第一组调用了迭代器。这是因为我正在从TypeScript进行编译。如果我对JS使用本机异步/等待,那么它就可以工作。这是因为引用async docs for AsyncFunction

  

由于JavaScript的局限性,我们只能检测本地异步功能,而不能进行跨语言实现。

因此,如果您使用异步库中的asyncify包装迭代器,则可以从迭代器内部返回而不使用回调:

  

如果您正在通过转译器(例如Babel)使用异步函数,则仍必须使用asyncify封装该函数,因为异步函数将被编译为返回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();

答案 1 :(得分:0)

没有。 async模块为不能或不使用Promises的人提供实用程序和抽象。他们不混合。

更不用说,当你有myList时,所有请求都已发送。

async.mapLimit仅适用于接受回调的函数,而不适用于返回Promise的函数。

您可能想要的是使用Bluebird的Promise.map() with the concurrency operator