使事件发射器同步

时间:2019-06-12 04:53:43

标签: javascript

我正在试用proxy-lists软件包,该软件包使用事件发射器接收代理。

我创建了以下示例:

const ProxyLists = require('proxy-lists');

function main() {

    const options = {
        countries: null
    };

    // `gettingProxies` is an event emitter object.
    const gettingProxies = ProxyLists.getProxies(options);

    let data = []
    gettingProxies.on('data', function (proxies) {
        console.log(proxies);
        data.push(proxies)
        if (data.length > 1000) {
            return data
        }
    });
}

console.log("First Call");
const res = main()
console.log(res);
console.log("Last Call");

但是,我收到以下输出:

First Call
undefined
Last Call
[ { ipAddress: 'ip-192-169-156-211.ip.secureserver.net',
    port: 52324,
    country: null,
    source: 'rosinstrument' },
  { ipAddress: 'ip-192-169-218-61.ip.secureserver.net',

如您所见,函数运行时已经调用了console.log。但是,我更喜欢以下 synchronous 顺序:

First Call
[ { ipAddress: '72.89.213.193.static.cust.telenor.com',
    port: 51024,
    country: 'us',
    source: 'rosinstrument' },
  { ipAddress: '50.250.56.129',
    port: 48380,
    country: 'us',
    source: 'rosinstrument' },
...
Last Call

有人建议我在做什么错吗?

2 个答案:

答案 0 :(得分:3)

我认为您可以将异步代码包装到Promise中,并用等待的值resolve将其包装,然后then调用所需的下一个代码,如下所示:

const ProxyLists = require('proxy-lists');

function main() {
    return new Promise((resolve, reject) => {
        const options = {
            countries: null
        };

        // `gettingProxies` is an event emitter object.
        const gettingProxies = ProxyLists.getProxies(options);

        let data = []

        gettingProxies.on('data', function (proxies) {
            console.log(proxies);
            data.push(proxies)
            if (data.length > 1000) {
                resolve(data);
            }
        });
    })
}

console.log("First Call");

main().then((res) => {
    console.log(res);
    console.log("Last Call");
})

如果您正在使用babel或打字稿之类的东西,甚至可以像下面这样使用async / await

console.log("First Call");
var res = await main();
console.log(res);
console.log("Last Call");

答案 1 :(得分:2)

您可以使用ES7的async/await语法使异步代码 出现为同步代码:

const ProxyLists = require('proxy-lists');

function getProxies() {
    const options = {
        countries: null
    };

    // `gettingProxies` is an event emitter object.
    const gettingProxies = ProxyLists.getProxies(options);

    let data = []
    return new Promise(function(resolve, reject) { // wrap in promise
        gettingProxies.on('data', function (proxies) {
            console.log(proxies);
            data.push(proxies)
            if (data.length > 1000) {
                resolve(data);
            }
        });
    }); 
}

async function main() {
    console.log("First Call");
    const res = await getProxies();
    console.log(res); // can be used
    console.log("Last Call");
}

main();

在这里,我将main()设为了async函数,使我可以使用await关键字,该关键字实际上是从{中获取解析值(即:dataPromise方法返回的{1}}。在后台,这实际上只是getProxies()的语法糖,因此它仍然是异步代码。