02a832a8d6ec3f1d6d0e67dfff9ae2d6b1d69df993ac55d9f9d3c8779e5779d60072ce138a59c85d60d445e56618a25c22ce5bc475542ebc13eabe324d42b2 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #ifndef PROMISE_RUNNER_H
  2. #define PROMISE_RUNNER_H
  3. #include <node_api.h>
  4. #include "wasm/include.h"
  5. #include <napi.h>
  6. using namespace Napi;
  7. class PromiseRunner {
  8. public:
  9. const Env env;
  10. Promise::Deferred deferred;
  11. PromiseRunner(Env env) : env(env), deferred(Promise::Deferred::New(env)) {
  12. napi_status status = napi_create_async_work(env, nullptr, env.Undefined(),
  13. onExecute, onWorkComplete, this, &work);
  14. if (status != napi_ok) {
  15. work = nullptr;
  16. const napi_extended_error_info *error_info = 0;
  17. napi_get_last_error_info(env, &error_info);
  18. if (error_info->error_message) {
  19. Error::New(env, error_info->error_message).ThrowAsJavaScriptException();
  20. } else {
  21. Error::New(env).ThrowAsJavaScriptException();
  22. }
  23. }
  24. }
  25. virtual ~PromiseRunner() {}
  26. Value queue() {
  27. if (work) {
  28. napi_status status = napi_queue_async_work(env, work);
  29. if (status != napi_ok) {
  30. onError(Error::New(env));
  31. }
  32. }
  33. return deferred.Promise();
  34. }
  35. private:
  36. napi_async_work work;
  37. std::string error;
  38. static void onExecute(napi_env env, void *this_pointer) {
  39. PromiseRunner* self = (PromiseRunner*) this_pointer;
  40. try {
  41. self->execute();
  42. } catch (std::exception &err) {
  43. self->error = err.what();
  44. }
  45. }
  46. static void onWorkComplete(napi_env env, napi_status status, void *this_pointer) {
  47. PromiseRunner* self = (PromiseRunner*) this_pointer;
  48. if (status != napi_cancelled) {
  49. HandleScope scope(self->env);
  50. if (status == napi_ok) {
  51. status = napi_delete_async_work(self->env, self->work);
  52. if (status == napi_ok) {
  53. if (self->error.size() == 0) {
  54. self->onOK();
  55. } else {
  56. self->onError(Error::New(self->env, self->error));
  57. }
  58. delete self;
  59. return;
  60. }
  61. }
  62. }
  63. // fallthrough for error handling
  64. const napi_extended_error_info *error_info = 0;
  65. napi_get_last_error_info(env, &error_info);
  66. if (error_info->error_message){
  67. self->onError(Error::New(env, error_info->error_message));
  68. } else {
  69. self->onError(Error::New(env));
  70. }
  71. delete self;
  72. }
  73. virtual void execute() {}
  74. virtual Value getResult() {
  75. return env.Null();
  76. }
  77. void onOK() {
  78. HandleScope scope(env);
  79. Value result = getResult();
  80. deferred.Resolve(result);
  81. }
  82. void onError(const Error &e) {
  83. deferred.Reject(e.Value());
  84. }
  85. };
  86. #endif