如果nodejs使用非阻塞IO,fs.readFileSync如何实现?

我在文件系统库中看到很多同步function。 如fs.readFileSync(filename, [options])

如果节点具有asynchronous/非阻塞IO并且没有睡眠方法,那么这些函数是如何(以及为什么)实现的?我可以使用相同的机制来实现其他同步函数吗?

 fs.readFileSync() 

真的只是一个包装的

 fs.readSync() 

function。 所以问题是fs.readSync()与fs.read()相比如何实现。 如果你看看这两个函数的实现,他们都利用绑定模块。 在这种情况下哪个是初始化的

 var binding = process.binding('fs'). 

和电话是

 binding.read(fd, buffer, offset, length, position, wrapper);//async var r = binding.read(fd, buffer, offset, length, position);//sync 

分别。 一旦我们在“绑定”模块中,我们就出现在v8中,node _ #####。cc land。 binding('fs')的实现可以在node_file.cc中的节点库代码中find。 节点引擎为C ++调用提供重载,一个调用callback,一个不调用callback。 node_file.cc代码利用了req_wrap类。 这是v8引擎的包装。 在node_file.cc中我们看到这个:

 #define ASYNC_CALL(func, callback, ...) \ FSReqWrap* req_wrap = new FSReqWrap(#func); \ int r = uv_fs_##func(uv_default_loop(), &req_wrap->req_, \ __VA_ARGS__, After); \ req_wrap->object_->Set(oncomplete_sym, callback); \ req_wrap->Dispatched(); \ if (r < 0) { \ uv_fs_t* req = &req_wrap->req_; \ req->result = r; \ req->path = NULL; \ req->errorno = uv_last_error(uv_default_loop()).code; \ After(req); \ } \ return scope.Close(req_wrap->object_); #define SYNC_CALL(func, path, ...) \ fs_req_wrap req_wrap; \ int result = uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \ if (result < 0) { \ int code = uv_last_error(uv_default_loop()).code; \ return ThrowException(UVException(code, #func, "", path)); \ } 

请注意,SYNC_CALL使用不同的req-wrap。 这里是req_wrap.h中ASYNC方法的相关req_wrap构造函数的代码

 ReqWrap() { v8::HandleScope scope; object_ = v8::Persistent<v8::Object>::New(v8::Object::New()); v8::Local<v8::Value> domain = v8::Context::GetCurrent() ->Global() ->Get(process_symbol) ->ToObject() ->Get(domain_symbol); if (!domain->IsUndefined()) { // fprintf(stderr, "setting domain on ReqWrap\n"); object_->Set(domain_symbol, domain); } ngx_queue_insert_tail(&req_wrap_queue, &req_wrap_queue_); } 

注意这个函数正在创build一个新的v8范围对象来处理这个事件的运行。 这是asynchronous事件的asynchronous部分发生的地方。 v8引擎启动一个新的javascript解释环境来分别处理这个特定的调用。 简而言之,在不构build/修改自己的节点版本的情况下,不能像节点那样实现自己的asynchronous/同步版本的调用。 这就是说,asynchronous真的只适用于I / O操作。 也许是为什么你认为你需要事物更加同步的描述是有序的。 一般来说,如果你认为节点不支持你想要做的事情,那么你只是没有充分利用callback机制来充分发挥它的潜力。

话虽如此,如果您需要asynchronous行为,您可以考虑使用事件节点模块来实现您自己的事件处理程序。 你可以考虑本地扩展,如果有什么东西你迫切需要做同步,但是,我强烈build议不要这样做。 考虑如何在asynchronous事件循环内工作以获得您需要这样做的事情。 拥抱这种思维方式,或转换到另一种语言。

强制语言处理事情的方式不想处理它们是编写错误代码的好方法。