@@ -243,7 +243,9 @@ be safely released.
243
243
Note that ` Napi::AsyncProgressWorker::ExecutionProcess::Send ` merely guarantees
244
244
** eventual** invocation of ` Napi::AsyncProgressWorker::OnProgress ` , which means
245
245
multiple send might be coalesced into single invocation of ` Napi::AsyncProgressWorker::OnProgress `
246
- with latest data.
246
+ with latest data. If you would like to guarantee that there is one invocation of
247
+ ` OnProgress ` for every ` Send ` call, you should use the ` Napi::AsyncProgressQueueWorker `
248
+ class instead which is documented further down this page.
247
249
248
250
``` cpp
249
251
void Napi::AsyncProgressWorker::ExecutionProcess::Send (const T* data, size_t count) const;
@@ -269,7 +271,8 @@ function runs in the background out of the **event loop** thread and at the end
269
271
the `Napi::AsyncProgressWorker::OnOK` or `Napi::AsyncProgressWorker::OnError` function will be
270
272
called and are executed as part of the event loop.
271
273
272
- The code below shows a basic example of the `Napi::AsyncProgressWorker` implementation:
274
+ The code below shows a basic example of the `Napi::AsyncProgressWorker` implementation along with an
275
+ example of how the counterpart in Javascript would appear:
273
276
274
277
```cpp
275
278
#include <napi.h>
@@ -281,28 +284,38 @@ using namespace Napi;
281
284
282
285
class EchoWorker : public AsyncProgressWorker<uint32_t> {
283
286
public:
284
- EchoWorker(Function& callback , std::string& echo)
285
- : AsyncProgressWorker(callback ), echo(echo) {}
287
+ EchoWorker(Function& okCallback , std::string& echo)
288
+ : AsyncProgressWorker(okCallback ), echo(echo) {}
286
289
287
290
~EchoWorker() {}
288
- // This code will be executed on the worker thread
289
- void Execute(const ExecutionProgress& progress) {
290
- // Need to simulate cpu heavy task
291
- for (uint32_t i = 0; i < 100; ++i) {
292
- progress.Send(&i, 1)
293
- std::this_thread::sleep_for(std::chrono::seconds(1));
291
+
292
+ // This code will be executed on the worker thread
293
+ void Execute(const ExecutionProgress& progress) {
294
+ // Need to simulate cpu heavy task
295
+ // Note: This Send() call is not guaranteed to trigger an equal
296
+ // number of OnProgress calls (read documentation above for more info)
297
+ for (uint32_t i = 0; i < 100; ++i) {
298
+ progress.Send(&i, 1)
299
+ }
300
+ }
301
+
302
+ void OnError(const Error &e) {
303
+ HandleScope scope(Env());
304
+ // Pass error onto JS, no data for other parameters
305
+ Callback().Call({String::New(Env(), e.Message())});
294
306
}
295
- }
296
307
297
- void OnOK() {
298
- HandleScope scope(Env());
299
- Callback().Call({Env().Null(), String::New(Env(), echo)});
300
- }
308
+ void OnOK() {
309
+ HandleScope scope(Env());
310
+ // Pass no error, give back original data
311
+ Callback().Call({Env().Null(), String::New(Env(), echo)});
312
+ }
301
313
302
- void OnProgress(const uint32_t* data, size_t /* count */) {
303
- HandleScope scope(Env());
304
- Callback().Call({Env().Null(), Env().Null(), Number::New(Env(), *data)});
305
- }
314
+ void OnProgress(const uint32_t* data, size_t /* count */) {
315
+ HandleScope scope(Env());
316
+ // Pass no error, no echo data, but do pass on the progress data
317
+ Callback().Call({Env().Null(), Env().Null(), Number::New(Env(), *data)});
318
+ }
306
319
307
320
private:
308
321
std::string echo;
@@ -327,12 +340,23 @@ using namespace Napi;
327
340
328
341
Value Echo (const CallbackInfo& info) {
329
342
// We need to validate the arguments here
330
- Function cb = info[ 1] .As<Function >();
331
343
std::string in = info[ 0] .As<String >();
344
+ Function cb = info[ 1] .As<Function >();
332
345
EchoWorker* wk = new EchoWorker(cb, in);
333
346
wk->Queue();
334
347
return info.Env().Undefined();
335
348
}
349
+
350
+ // Register the native method for JS to access
351
+ Object Init(Env env, Object exports)
352
+ {
353
+ exports.Set(String::New(env, "echo"), Function::New(env, Echo));
354
+
355
+ return exports;
356
+ }
357
+
358
+ // Register our native addon
359
+ NODE_API_MODULE(nativeAddon, Init)
336
360
```
337
361
338
362
The implementation of a `Napi::AsyncProgressWorker` can be used by creating a
@@ -341,6 +365,20 @@ asynchronous task ends and other data needed for the computation. Once created,
341
365
the only other action needed is to call the `Napi::AsyncProgressWorker::Queue`
342
366
method that will queue the created worker for execution.
343
367
368
+ Lastly, the following Javascript (ES6+) code would be associated the above example:
369
+
370
+ ```js
371
+ const { nativeAddon } = require('binding.node');
372
+
373
+ const exampleCallback = (errorResponse, okResponse, progressData) => {
374
+ // Use the data accordingly
375
+ // ...
376
+ };
377
+
378
+ // Call our native addon with the paramters of a string and a function
379
+ nativeAddon.echo("example", exampleCallback);
380
+ ```
381
+
344
382
# AsyncProgressQueueWorker
345
383
346
384
` Napi::AsyncProgressQueueWorker ` acts exactly like ` Napi::AsyncProgressWorker `
@@ -379,7 +417,9 @@ void Napi::AsyncProgressQueueWorker::ExecutionProcess::Send(const T* data, size_
379
417
380
418
## Example
381
419
382
- The code below shows a basic example of the ` Napi::AsyncProgressQueueWorker ` implementation:
420
+ The code below show an example of the `Napi::AsyncProgressQueueWorker` implementation, but
421
+ also demonsrates how to use multiple `Napi::Function`'s if you wish to provide multiple
422
+ callback functions for more object oriented code:
383
423
384
424
```cpp
385
425
#include <napi.h>
@@ -391,31 +431,55 @@ using namespace Napi;
391
431
392
432
class EchoWorker : public AsyncProgressQueueWorker<uint32_t> {
393
433
public:
394
- EchoWorker(Function& callback, std::string& echo)
395
- : AsyncProgressQueueWorker(callback), echo(echo) {}
434
+ EchoWorker(Function& okCallback, Function& errorCallback, Function& progressCallback, std::string& echo)
435
+ : AsyncProgressQueueWorker(okCallback), echo(echo) {
436
+ // Set our function references to use them below
437
+ this->errorCallback.Reset(errorCallback, 1);
438
+ this->progressCallback.Reset(progressCallback, 1);
439
+ }
396
440
397
441
~EchoWorker() {}
398
- // This code will be executed on the worker thread
399
- void Execute(const ExecutionProgress& progress) {
400
- // Need to simulate cpu heavy task
401
- for (uint32_t i = 0; i < 100; ++i) {
402
- progress.Send(&i, 1);
403
- std::this_thread::sleep_for(std::chrono::seconds(1));
442
+
443
+ // This code will be executed on the worker thread
444
+ void Execute(const ExecutionProgress& progress) {
445
+ // Need to simulate cpu heavy task to demonstrate that
446
+ // every call to Send() will trigger an OnProgress function call
447
+ for (uint32_t i = 0; i < 100; ++i) {
448
+ progress.Send(&i, 1);
449
+ }
404
450
}
405
- }
406
451
407
- void OnOK() {
408
- HandleScope scope(Env());
409
- Callback().Call({Env().Null(), String::New(Env(), echo)});
410
- }
452
+ void OnOK() {
453
+ HandleScope scope(Env());
454
+ // Call our onOkCallback in javascript with the data we were given originally
455
+ Callback().Call({String::New(Env(), echo)});
456
+ }
457
+
458
+ void OnError(const Error &e) {
459
+ HandleScope scope(Env());
460
+
461
+ // We call our callback provided in the constructor with 2 parameters
462
+ if (!this->errorCallback.IsEmpty()) {
463
+ // Call our onErrorCallback in javascript with the error message
464
+ this->errorCallback.Call(Receiver().Value(), {String::New(Env(), e.Message())});
465
+ }
466
+ }
411
467
412
- void OnProgress(const uint32_t* data, size_t /* count */) {
413
- HandleScope scope(Env());
414
- Callback().Call({Env().Null(), Env().Null(), Number::New(Env(), *data)});
415
- }
468
+ void OnProgress(const uint32_t* data, size_t /* count */) {
469
+ HandleScope scope(Env());
470
+
471
+ if (!this->progressCallback.IsEmpty()) {
472
+ // Call our onProgressCallback in javascript with each integer from 0 to 99 (inclusive)
473
+ // as this function is triggered from the above Send() calls
474
+ this->progressCallback.Call(Receiver().Value(), {Number::New(Env(), *data)});
475
+ }
476
+ }
416
477
417
478
private:
418
479
std::string echo;
480
+ FunctionReference progressCallback;
481
+ FunctionReference errorCallback;
482
+
419
483
};
420
484
```
421
485
@@ -439,12 +503,25 @@ using namespace Napi;
439
503
440
504
Value Echo (const CallbackInfo& info) {
441
505
// We need to validate the arguments here.
442
- Function cb = info[1].As<Function>();
443
506
std::string in = info[ 0] .As<String >();
444
- EchoWorker* wk = new EchoWorker(cb, in);
507
+ Function errorCb = info[ 1] .As<Function >();
508
+ Function okCb = info[ 2] .As<Function >();
509
+ Function progressCb = info[ 3] .As<Function >();
510
+ EchoWorker* wk = new EchoWorker(okCb, errorCb, progressCb, in);
445
511
wk->Queue();
446
512
return info.Env().Undefined();
447
513
}
514
+
515
+ // Register the native method for JS to access
516
+ Object Init(Env env, Object exports)
517
+ {
518
+ exports.Set(String::New(env, "echo"), Function::New(env, Echo));
519
+
520
+ return exports;
521
+ }
522
+
523
+ // Register our native addon
524
+ NODE_API_MODULE(nativeAddon, Init)
448
525
```
449
526
450
527
The implementation of a `Napi::AsyncProgressQueueWorker` can be used by creating a
@@ -453,4 +530,28 @@ asynchronous task ends and other data needed for the computation. Once created,
453
530
the only other action needed is to call the `Napi::AsyncProgressQueueWorker::Queue`
454
531
method that will queue the created worker for execution.
455
532
533
+ Lastly, the following Javascript (ES6+) code would be associated the above example:
534
+
535
+ ```js
536
+ const { nativeAddon } = require('binding.node');
537
+
538
+ const onErrorCallback = (msg) => {
539
+ // Use the data accordingly
540
+ // ...
541
+ };
542
+
543
+ const onOkCallback = (echo) => {
544
+ // Use the data accordingly
545
+ // ...
546
+ };
547
+
548
+ const onProgressCallback = (num) => {
549
+ // Use the data accordingly
550
+ // ...
551
+ };
552
+
553
+ // Call our native addon with the paramters of a string and three callback functions
554
+ nativeAddon.echo("example", onErrorCallback, onOkCallback, onProgressCallback);
555
+ ```
556
+
456
557
[ `Napi::AsyncWorker` ] : ./async_worker.md
0 commit comments