【问题标题】:Await for an async queue to be proceeded (async module)等待异步队列进行(异步模块)
【发布时间】:2019-03-04 14:59:04
【问题描述】:

我正在尝试使用 nodejs 和异步模块构建一个队列,但它没有按预期工作。

这是我的代码:

const async = require('async');

const queueSize = 10;
const taskHandler = function (task, done) {
    task(done);
};

const myQueue = async.queue(taskHandler, queueSize);

myQueue.drain = function () {
    console.log('The queue is now empty.');
};

function delay() {
    return new Promise(resolve => setTimeout(resolve, 1000));
}

async function delayedLog(item) {
    await delay();
    console.log(item);
}

const run = async () => {
    for (let item = 0; item < 30; item++) {
        myQueue.push(async function (done) {
            await delayedLog(item)
            done();
        });
    }
}

(async () => {
    console.log('START');
    await run();
    console.log('END);
})()

我想要什么:

START
// logs from delayedLog
END 

输出:

START
END 
// logs from delayedLog

如您所见,等待不起作用。我试图对模块进行承诺,但问题仍然存在。我尝试使用 d3-queue,但遇到了完全相同的问题。

有什么建议吗?

【问题讨论】:

    标签: javascript asynchronous async-await queue async.js


    【解决方案1】:

    正如@Chiến Nghê 所说,您正在使用一些不需要的异步/等待,但这是另一个问题。

    您的 await 最终无法正常工作,因为您的 drain 函数在队列末尾被调用并且它没有返回一个 Promise。

    你必须承诺你的功能,这里有一个示例:

    function end() {
        return new Promise((resolve, reject) => {
            myQueue.drain = function () {
                console.log('The queue is now empty.');
                resolve();
            };
        })
    }
    

    然后你可以在你的结束函数上使用你的异步等待:

    (async () => {
        console.log('START');
        run();
        await end();
        console.log('END');
    })()
    

    输出:

    START
    // a lot of logs
    END 
    

    【讨论】:

      【解决方案2】:

      您的程序按原样运行。实际上你不需要为函数run() 声明async。该函数只是将 30 个异步任务放入队列以供稍后执行,然后结束。

      我不知道你想要什么,但如果你想要 console.log('END') 逻辑只执行队列中的每个异步任务完成。请将其移至队列的drain() 函数。

      【讨论】:

      • 目的是等待队列结束以处理其他东西,真正的代码启动倍数发布到服务器,我必须等待所有响应才能在数据库中插入数据用其他数据再做一次 (async () => { console.log('START'); await run(process1); await run(process1); console.log('END); })()
      • sorry I hit enter too many times 最终目的是这样的 main (async () => { console.log('START'); await run( process1); await saveToDB(responses1) ; 等待运行(process2); 等待 saveToDB(responses2); 等待运行(process3); 等待 saveToDB(responses3); console.log('END); })()
      • 我的意见是你把你的“其他东西”放到队列 drain() 函数中。因为一旦您将任务注册到异步队列,除了 drain() 之外没有其他地方可以作为结束队列事件检测的点。这就是为什么存在这个 drain() 函数的原因。
      • 没错!排水是唯一的方法,所以我做了@Curse所说的我承诺并在主进程中等待它所以我可以以干净的方式链接多个任务(它当然是更大项目的一部分,所以我不能直接将代码保留在排水功能),谢谢
      • 顺便说一句,关于没有 nedded async / await
      猜你喜欢
      • 2019-11-17
      • 2013-04-12
      • 1970-01-01
      • 2023-03-12
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      相关资源
      最近更新 更多