Idle 空转函数

一个空转句柄会在事件循环的每次循环之初被执行。

c++

#include <napi.h>
#include <uv.h>

namespace __idle__ {

unsigned int idle_times = 0;
uv_idle_t *idle = nullptr;

void test_idle(uv_idle_t *handle) {
  idle_times--;

  printf("Idle callback called. %u times left.\n", idle_times);

  if (idle_times == 0) {
    idle = nullptr;
    uv_idle_stop(handle);
    delete handle;
  }
}

Napi::Value Idle(const Napi::CallbackInfo &info) {
  Napi::Env env = info.Env();

  if (idle != 0) {
    Napi::TypeError::New(env, "Idle already started").ThrowAsJavaScriptException();
    return env.Null();
  }

  idle_times = info[0].As<Napi::Number>().Uint32Value();

  idle = new uv_idle_t();
  uv_idle_init(uv_default_loop(), idle);

  uv_idle_start(idle, test_idle);

  return env.Null();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "startIdle"), Napi::Function::New(env, Idle));
  return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

} // namespace __idle__
c++

javascript

import { idle } from '../lib/binding.cjs'

idle.startIdle(100)

try {
  idle.startIdle(1)
} catch (e) {
  console.error(e)
}

let times = 100
function tick() {
  times--
  console.log(`还剩 ${times} 次 tick。`)

  if (times === 0) return

  setImmediate(tick)
}

setImmediate(tick)
javascript

项目地址

源码地址