@@ -132,6 +132,22 @@ void {{ cppClassName }}::{{ field.name }}_asyncAfter(uv_work_t* req, int status)
132132
133133 TryCatch tryCatch;
134134 Handle<Value> result = instance->{{ field.name }}->Call ({{ field.args |jsArgsCount }}, argv);
135+
136+ if (result->IsObject ()) {
137+ const char * constructorName = **(new NanUtf8String (result->ToObject ()->GetConstructorName ()));
138+ string promiseConName (" Promise" );
139+
140+ if (promiseConName.compare (constructorName) == 0 ) {
141+ // we can be reasonbly certain that the result is a promise
142+ Local<Object> promise = result->ToObject ();
143+
144+ NanAssignPersistent (baton->promise , promise);
145+
146+ uv_queue_work (uv_default_loop (), &baton->req , {{ field.name }}_asyncWork, {{ field.name }}_asyncPromisePolling);
147+ return ;
148+ }
149+ }
150+
135151 {{ field.returnType }} resultStatus;
136152
137153 {%each field|returnsInfo true false as _return%}
@@ -151,6 +167,52 @@ void {{ cppClassName }}::{{ field.name }}_asyncAfter(uv_work_t* req, int status)
151167 {%endeach%}
152168 baton->done = true ;
153169}
170+
171+ void {{ cppClassName }}::{{ field.name }}_asyncPromisePolling(uv_work_t * req, int status) {
172+ NanScope ();
173+
174+ {{ field.name |titleCase }}Baton* baton = static_cast <{{ field.name |titleCase }}Baton*>(req->data );
175+ Local<Object> promise = NanNew<Object>(baton->promise );
176+ NanCallback* isPendingFn = new NanCallback (promise->Get (NanNew (" isPending" )).As <Function>());
177+ Local<Value> argv[0 ];
178+ Local<Boolean> isPending = isPendingFn->Call (0 , argv)->ToBoolean ();
179+
180+ if (isPending->Value ()) {
181+ uv_queue_work (uv_default_loop (), &baton->req , {{ field.name }}_asyncWork, {{ field.name }}_asyncPromisePolling);
182+ return ;
183+ }
184+
185+ NanCallback* isFulfilledFn = new NanCallback (promise->Get (NanNew (" isFulfilled" )).As <Function>());
186+ Local<Boolean> isFulfilled = isFulfilledFn->Call (0 , argv)->ToBoolean ();
187+
188+ if (isFulfilled->Value ()) {
189+ NanCallback* resultFn = new NanCallback (promise->Get (NanNew (" value" )).As <Function>());
190+ Handle<Value> result = resultFn->Call (0 , argv);
191+ {{ field.returnType }} resultStatus;
192+
193+ {%each field|returnsInfo true false as _return%}
194+ if (result.IsEmpty () || result->IsNativeError ()) {
195+ baton->result = {{ field.returnError }};
196+ }
197+ else if (!result->IsNull () && !result->IsUndefined ()) {
198+ {{ _return.cppClassName }}* wrapper = ObjectWrap::Unwrap<{{ _return.cppClassName }}>(result->ToObject ());
199+ wrapper->selfFreeing = false ;
200+
201+ baton->{{ _return.name }} = wrapper->GetRefValue ();
202+ baton->result = {{ field.returnSuccess }};
203+ }
204+ else {
205+ baton->result = {{ field.returnNoResults }};
206+ }
207+ {%endeach%}
208+ baton->done = true ;
209+ }
210+ else {
211+ // promise was rejected
212+ baton->result = {{ field.returnError }};
213+ baton->done = false ;
214+ }
215+ }
154216 {%endif%}
155217 {%endif%}
156218{%endeach%}
0 commit comments