Napi::ThreadSafeFunction 提供了两种调用 JavaScript 函数的方式:BlockingCall 和 NonBlockingCall。这两者的区别在于它们如何处理线程同步和执行时机。
- BlockingCall(阻塞调用)
行为:使用 BlockingCall 时,工作线程会等待(阻塞),直到 JavaScript 函数在主线程中执行完毕后再继续执行。
线程同步:保证在 JavaScript 函数执行完成之前,工作线程不会继续运行。
适用场景:通常在工作线程依赖于 JavaScript 函数的结果时使用。比如,工作线程的后续操作需要基于 JavaScript 的返回值或结果。
性能影响:由于工作线程要等待 JavaScript 函数执行完毕,可能会导致性能瓶颈,尤其当 JavaScript 函数运行时间较长时。
示例:
tsfn.BlockingCall([](Napi::Env env, Napi::Function jsCallback) {
// 这段代码会阻塞工作线程,直到 JavaScript 函数执行完毕。
});
在这种情况下,工作线程必须等 JavaScript 函数执行完才能继续运行。
-NonBlockingCall(非阻塞调用)
行为:使用 NonBlockingCall 时,工作线程不会等待 JavaScript 函数执行完毕。它是异步的,工作线程会立即继续执行,而不等待 JavaScript 函数的结果。
线程同步:允许工作线程在不等待 JavaScript 函数完成的情况下继续执行,JavaScript 函数会在稍后的事件循环中执行。
适用场景:当工作线程不依赖于 JavaScript 函数的返回结果时使用。比如,工作线程的任务可以独立于 JavaScript 的执行结果。
性能影响:因为工作线程不需要等待 JavaScript 执行,通常能提升性能,特别是在需要处理大量并发任务时。
tsfn.NonBlockingCall([](Napi::Env env, Napi::Function jsCallback) {
// 工作线程不会等待 JavaScript 函数的执行,直接继续运行。
});
在这种情况下,工作线程无需等待 JavaScript 函数执行完毕,可以立即执行后续任务。
- 关键区别:
特性 BlockingCall(阻塞调用) NonBlockingCall(非阻塞调用)
执行方式 工作线程会等待 JS 函数执行完毕 工作线程不会等待,立即继续执行
线程同步 同步,阻塞工作线程 异步,不阻塞工作线程
性能影响 如果 JS 函数执行时间较长,可能影响性能 工作线程不等待,提升并发性能
适用场景 工作线程依赖 JS 函数结果时使用 工作线程不依赖 JS 函数结果时使用
使用场景:
当需要确保 JavaScript 函数执行完毕后工作线程才能继续执行时,使用 BlockingCall。
当不需要等待 JavaScript 函数执行结果时,为了提升性能,使用 NonBlockingCall