gpt4 book ai didi

javascript - Nodejs - libuv 非阻塞事件回调

转载 作者:行者123 更新时间:2023-11-30 14:00:44 25 4
gpt4 key购买 nike

我正在尝试使用需要 native 模块支持的 Node.Js 构建应用程序。我已经通过应用程序使用了 libuv 库,并且我能够使大多数异步方法工作,除了我必须实现进度事件回调的部分。我想异步实现进度事件回调,而不阻塞 Node.js 事件循环。

代码片段如下:

native.cc

#include <node.h>
#include <uv.h>
#include "nbind/nbind.h"

using v8::Isolate;
using v8::HandleScope;


int FileProgressCallback(uint64_t const sent, uint64_t const total, void const *const data) {
nbind::cbFunction cb = *((nbind::cbFunction *) data);
cb(sent, total);
return 0;
}

class WorkerFileTransfer {
public:
WorkerFileTransfer(std::string path, nbind::cbFunction cb) :
callback(cb), path(path) {};

uv_work_t worker;
nbind::cbFunction callback;

bool error;
std::string errorMsg;

std::string path;
};

void FileTransferDone(uv_work_t *order, int status) {
Isolate *isolate = Isolate::GetCurrent();
HandleScope handleScope(isolate);

WorkerFileTransfer *work = static_cast< WorkerFileTransfer * >( order->data );

if (work->error) {
work->callback.call<void>(work->errorMsg.c_str(), work->output);
} else {
ThirdPartyLibraryFileCopy(work->path.c_str(), FileProgressCallback, (const void *) &work->callback);
}

// Memory cleanup
work->callback.reset();
delete work;
}

void FileTransferRunner(uv_work_t *order) {
WorkerFileTransfer *work = static_cast< WorkerFileTransfer * >( order->data );

try {
work->output = true;
}
catch (...) {
work->error = true;
work->errorMsg = "Error occured while executing the method...";
}
}

void FileTransfer(const std::string path, nbind::cbFunction &callback) {
WorkerFileTransfer *work = new WorkerFileTransfer(path, callback);

work->worker.data = work;
work->path = path;
work->error = false;

uv_queue_work(uv_default_loop(), &work->worker, FileTransferRunner, FileTransferDone);
}

function(FileTransfer);

test.js

FileTransfer(
'/path/file.txt',
(sent, total) => {

console.log(`sent`, sent);
console.log('total', total);
}
);

由于以下几行,我能够完成文件传输,但 Node.Js 事件循环在此处被阻止。

void FileTransferDone(uv_work_t *order, int status) {
...

ThirdPartyLibraryFileCopy(work->path.c_str(), FileProgressCallback, (const void *) &work->callback);

...
}

当我将行 ThirdPartyLibraryFileCopy(work->path.c_str(), FileProgressCallback, (const void *) &work->callback); 移动到 FileTransferRunner(uv_work_t *order) 方法,然后我在 javascript 回调函数中没有得到任何输出。

如何在不阻塞 Node.Js 事件循环的情况下异步获取 javascript 回调函数中的进度值?

最佳答案

根据 uv_queue_work 文档:http://docs.libuv.org/en/v1.x/threadpool.html#c.uv_queue_work工作回调(在您的情况下为 FileTransferRunner)在线程池上运行,而完成的回调(在您的情况下为 FileTransferDone)在循环线程上运行。因此,如果对后者执行阻塞操作,就会阻塞循环。

如果您想定期发送进度报告,则此模型不适合您。您可以使用异步句柄 uv_async_t 并使用工作函数中的 uv_async_send(线程安全)报告进度。或者使用多个工作请求来发送 block (这可能会更慢)。

关于javascript - Nodejs - libuv 非阻塞事件回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56347264/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com