I figured it out, NodeJS does not check to see if any microtasks need to be run before taking a nice nap for timers, adding "isolate->RunMicrotasks();" just after resolving fixes it for me, but this a real bug.At least when native c++ addons are calling resolve, nothing happens until RunMicrotasks() is calledI am thinking up ways to fix this, but i don't know at the moment the best place to insert RunMicrotasks(), probably just before "uv_run(env.event_loop(), UV_RUN_ONCE);" in node.cc, because that is when it takes napsOn Mon, Dec 5, 2016 at 2:31 AM, Daniel Kluss <code...@gmail.com> wrote:When setTimeout is used promises wait for it to complete, instead of going quickly like normalBelow is the snippets involved, i can post whole thing. I think i must be doing something wrong, I don't assume a bug in node or libuv just yet.Also, since resolve is called between "staticAfterWork" and "staticAfterWork done", why does the 'then' message of timing not print between them.It appears the 'then' function calls get queued up for later, and the queue isn't run thru until after the timers queue if it has anything in it.using Windows 10x64, node 7.2 x64,command and outputnode --harmony test1188880625 staticDoWork1188880625 staticDoWork done1188880625 staticAfterWork1188880625 staticAfterWork donetest_no_timeout: 27.506ms1188880656 staticDoWork1188880687 staticDoWork done1188880718 staticAfterWork1188880718 staticAfterWork donetest_with_timeout: 3001.294msjs codefunction test_no_timeout() {console.time('test_no_timeout');intrinsics._promise_worker_sleep(1).then(()=>{console.timeEnd('test_no_timeout');setImmediate(test_with_timeout);});}function test_with_timeout() {setTimeout(()=>{}, 3000);console.time('test_with_timeout');intrinsics._promise_worker_sleep(1).then(()=>{console.timeEnd('test_with_timeout');});}test_no_timeout();c++ addontemplate<typename T>class WorkerArgsAndResolver {public:v8::Global<v8::Promise::Resolver> resolver;static void staticDoWork(uv_work_t* req) {printf("%u staticDoWork\n", GetTickCount());static_cast<T *>(req->data)->doWork(req);printf("%u staticDoWork done\n", GetTickCount());}static void staticAfterWork(uv_work_t* req, int status) {printf("%u staticAfterWork\n", GetTickCount());static_cast<T *>(req->data)->afterWork(req, status);delete static_cast<T *>(req->data);delete req;printf("%u staticAfterWork done\n", GetTickCount());}WorkerArgsAndResolver(const v8::FunctionCallbackInfo<v8::Value>& info) {v8::Isolate* isolate = v8::Isolate::GetCurrent();v8::HandleScope scope(isolate);auto LocalResolver = v8::Promise::Resolver::New(info.GetIsolate());info.GetReturnValue().Set(LocalResolver->GetPromise());resolver.Reset(isolate, LocalResolver);}void queue() {uv_work_t *work = new uv_work_t();work->data = this;uv_queue_work(uv_default_loop(), work, staticDoWork, staticAfterWork);}static void create(const v8::FunctionCallbackInfo<v8::Value>& info) {new T(info);}};class SleepEx_waar: public WorkerArgsAndResolver<SleepEx_waar>{public:uint32_t milliseconds{ 0 };uint32_t ret{ 0 };void doWork(uv_work_t* req) {auto beginTicks = GetTickCount();Sleep(milliseconds);auto finishTicks = GetTickCount();ret = finishTicks - beginTicks;}void afterWork(uv_work_t* req, int status) {v8::Isolate* isolate = v8::Isolate::GetCurrent();v8::HandleScope scope(isolate);resolver.Get(isolate)->Resolve(v8::Integer::NewFromUnsigned(isolate, ret));}SleepEx_waar(const v8::FunctionCallbackInfo<v8::Value>& info): WorkerArgsAndResolver(info) {milliseconds = info.Length()>0?info[0]->Uint32Value():0;queue();}};