node.js异步/等待或通用池导致无限循环?

时间:2018-10-14 10:54:15

标签: node.js async-await puppeteer

我试图创建一个自动化的工作脚本,应该使用多个multiple实例同时处理输入字符串。 任务队列和操纵up实例的数量由软件包通用池控制, 奇怪的是,当我在ubuntu或debian上运行脚本时,似乎陷入了无限循环。尝试运行无限数量的操纵up实例。在Windows上运行时,输出正常。

public void delete_thread(String thread)
{
    Cursor c = getApplicationContext().getContentResolver().query(
            Uri.parse("content://sms/"),new String[] {
                    "_id", "thread_id", "address", "person", "date","body" }, null, null, null);

    try {
        while (c.moveToNext())
        {
            int id = c.getInt(0);
            String address = c.getString(2);
            if (address.equals(thread))
            {
                getApplicationContext().getContentResolver().delete(
                        Uri.parse("content://sms/inbox/" + id), null, null);
            }
          //  Toast.makeText(Settings.this,nmr+id+"  02",Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {

        Toast.makeText(Settings.this,e.toString(),Toast.LENGTH_LONG).show();
    }
}

输出

const puppeteer = require('puppeteer');
const genericPool = require('generic-pool');
const faker = require('faker');
let options = require('./options');
let i = 0;
let proxies = [...options.proxy];

const pool = genericPool.createPool({
    create: async () => {
        i++;
        console.log(`create instance ${i}`);
        if (!proxies.length) {
            proxies = [...options.proxy];
        }
        let {control = null, proxy} = proxies.pop();
        let instance = await puppeteer.launch({
            headless: true,
            args: [
                `--proxy-server=${proxy}`,
            ]
        });
        instance._own = {
            proxy,
            tor: control,
            numInstance: i,
        };
        return instance;
    },
    destroy: async instance => {
        console.log('destroy instance', instance._own.numInstance);
        await instance.close()
    },
}, {
    max: 3, 
    min: 1, 
});

async function run(emails = []) {
    console.log('Processing', emails.length);
    const promises = emails.map(email => {
        console.log('Processing', email)
        pool.acquire()
            .then(browser => {
                console.log(`${email} handled`)
                pool.destroy(browser);})
    })
    await Promise.all(promises)
    await pool.drain();
    await pool.clear();
}

let emails = [a,b,c,d,e,];
run(emails)

是因为我的异步功能吗?我该如何解决? 感谢您的帮助!

编辑1.根据@James建议修改

2 个答案:

答案 0 :(得分:0)

您要从地图而不是await返回,也不要在await调用内destroy,返回结果,然后可以将其链接起来,例如。

const promises = emails.map(e => pool.acquire().then(pool.destroy));

或者,您也可以完全摆脱destroy,例如

pool.acquire().then(b => b.close())

答案 1 :(得分:0)

您要解决的主要问题

  

应该使用多个操纵up实例同时处理输入字符串。

承诺队列

您可以使用涉及简单的Promise队列的相当简单的解决方案。我们可以根据需要使用p-queue包来限制并发。我在多个抓取项目中使用了此工具,以便始终对其进行测试。

这里是使用方法。

// emails to handle
let emails = [a, b, c, d, e, ];

// create a promise queue
const PQueue = require('p-queue');

// create queue with concurrency, ie: how many instances we want to run at once
const queue = new PQueue({
    concurrency: 1
});

// single task processor
const createInstance = async (email) => {
    let instance = await puppeteer.launch({
        headless: true,
        args: [
            `--proxy-server=${proxy}`,
        ]
    });
    instance._own = {
        proxy,
        tor: control,
        numInstance: i,
    };
    console.log('email:', email)
    return instance;
}

// add tasks to queue
for (let email of emails) {
    queue.add(async () => createInstance(email))
}

通用池无限循环问题

我从您的示例代码中删除了所有与操纵related相关的代码,并看到它仍然如何产生无限的输出到控制台。

create instance 70326
create instance 70327
create instance 70328
create instance 70329
create instance 70330
create instance 70331
...

现在,如果您进行几次测试,则仅在代码崩溃时,它才会抛出循环。罪魁祸首是这个pool.acquire()承诺,只是在错误时重新排队。

要查找导致崩溃的原因,请使用以下事件,

pool.on("factoryCreateError", function(err) {
  console.log('factoryCreateError',err);
});

pool.on("factoryDestroyError", function(err) {
  console.log('factoryDestroyError',err);
});

与此有关的一些问题:

    如果工厂始终拒绝,{li> acquire()永远不会解析/拒绝here
  • 关于pool.js中的获取功能,here
  • .acquire()在资源创建失败时不会拒绝,here

祝你好运!