@@ -48,6 +48,57 @@ ROS 2 services provide a request-response communication pattern where clients se
4848  -  Asynchronous request handling with callbacks
4949-  ** Run Command** : ` node example/services/client/client-example.js ` 
5050
51+ #### Async Service Client (` client/async-client-example.js ` )  
52+ 
53+ ** Purpose** : Demonstrates modern async/await patterns for service communication, solving callback hell and providing cleaner error handling.
54+ 
55+ -  ** Service Type** : ` example_interfaces/srv/AddTwoInts ` 
56+ -  ** Service Name** : ` add_two_ints ` 
57+ -  ** Functionality** :
58+   -  Multiple examples showing different async patterns
59+   -  Simple async/await calls without callbacks
60+   -  Timeout handling with configurable timeouts
61+   -  Request cancellation using AbortController
62+   -  Sequential and parallel service calls
63+   -  Comprehensive error handling
64+ -  ** Features** :
65+   -  ** Modern JavaScript** : Clean async/await syntax instead of callback hell
66+   -  ** Timeout Support** : Built-in timeout handling with ` options.timeout ` 
67+   -  ** Cancellation** : Request cancellation using ` AbortController `  and ` options.signal ` 
68+   -  ** Error Types** : Specific error types (` TimeoutError ` , ` AbortError ` ) for better error handling (async only)
69+   -  ** Backward Compatible** : Works alongside existing callback-based ` sendRequest() ` 
70+   -  ** TypeScript Ready** : Full type safety with comprehensive TypeScript definitions
71+ -  ** Run Command** : ` node example/services/client/async-client-example.js ` 
72+ 
73+ ** Key API Differences** :
74+ 
75+ ``` javascript 
76+ client .sendRequest (request, (response ) =>  {
77+   console .log (' Response:'  , response .sum );
78+ });
79+ 
80+ try  {
81+   const  response  =  await  client .sendRequestAsync (request);
82+ 
83+   const  response  =  await  client .sendRequestAsync (request, { timeout:  5000  });
84+ 
85+   const  controller  =  new  AbortController ();
86+   const  response  =  await  client .sendRequestAsync (request, {
87+     signal:  controller .signal ,
88+   });
89+ 
90+   console .log (' Response:'  , response .sum );
91+ } catch  (error) {
92+   if  (error .name  ===  ' TimeoutError'  ) {
93+     console .log (' Request timed out'  );
94+   } else  if  (error .name  ===  ' AbortError'  ) {
95+     console .log (' Request was cancelled'  );
96+   } else  {
97+     console .error (' Service error:'  , error .message );
98+   }
99+ }
100+ ``` 
101+ 
51102### GetMap Service  
52103
53104#### Service Server (` service/getmap-service-example.js ` )  
@@ -129,6 +180,41 @@ ROS 2 services provide a request-response communication pattern where clients se
129180   Result: object { sum: 79n } 
130181    ``` 
131182
183+ ### Running the Async AddTwoInts Client Example  
184+ 
185+ 1 .  ** Prerequisites** : Ensure ROS 2 is installed and sourced
186+ 
187+ 2 .  ** Start the Service Server** : Use the same service server as above:
188+ 
189+    ``` bash 
190+    cd  /path/to/rclnodejs
191+    node example/services/service/service-example.js
192+    ``` 
193+ 
194+ 3 .  ** Start the Async Client** : In another terminal, run:
195+ 
196+    ``` bash 
197+    cd  /path/to/rclnodejs
198+    node example/services/client/async-client-example.js
199+    ``` 
200+ 
201+ 4 .  ** Expected Output** :
202+ 
203+    ** Service Server Terminal** : (Same as regular client)
204+ 
205+    ``` 
206+    Incoming request: object { a: 42n, b: 37n } 
207+    Sending response: object { sum: 79n } 
208+    -- 
209+     ``` 
210+ 
211+    ** Async Client Terminal** :
212+ 
213+    ``` 
214+    Sending: object { a: 42n, b: 37n } 
215+    Result: object { sum: 79n } 
216+     ``` 
217+ 
132218### Running the GetMap Service Example  
133219
1342201 .  ** Prerequisites** : Ensure ROS 2 is installed and sourced
@@ -236,8 +322,11 @@ This script automatically starts the service, tests the client, and cleans up.
236322
237323### Programming Patterns  
238324
239- -  ** Async/Await** : Modern JavaScript patterns for asynchronous operations
240- -  ** Callback Handling** : Response processing using callback functions
325+ -  ** Modern Async/Await** : Clean Promise-based service calls with ` sendRequestAsync() ` 
326+ -  ** Traditional Callbacks** : Response processing using callback functions with ` sendRequest() ` 
327+ -  ** Error Handling** : Proper error handling with try/catch blocks and specific error types (async only)
328+ -  ** Timeout Management** : Built-in timeout support to prevent hanging requests (async only)
329+ -  ** Request Cancellation** : AbortController support for user-cancellable operations (async only)
241330-  ** Resource Management** : Proper node shutdown and cleanup
242331-  ** Data Analysis** : Processing and interpreting received data
243332-  ** Visualization** : Converting data to human-readable formats
@@ -331,18 +420,23 @@ int8[] data
331420### Common Issues  
332421
3334221 .  ** Service Not Available** :
334- 
335423   -  Ensure the service server is running before starting the client
336424   -  Check that both use the same service name (` add_two_ints ` )
337425
3384262 .  ** Type Errors** :
339- 
340427   -  Ensure you're using ` BigInt() `  for integer values, not regular numbers
341428   -  Use ` response.template `  to get the correct response structure
342429
3434303 .  ** Client Hangs** :
344431   -  The client waits for service availability with a 1-second timeout
345432   -  If the service isn't available, the client will log an error and shut down
433+    -  For async clients, use timeout options: ` client.sendRequestAsync(request, { timeout: 5000 }) ` 
434+ 
435+ 4 .  ** Async/Await Issues**  (applies only to ` sendRequestAsync() ` ):
436+    -  ** Unhandled Promise Rejections** : Always use try/catch blocks around ` sendRequestAsync() ` 
437+    -  ** Timeout Errors** : Handle ` TimeoutError `  specifically for timeout scenarios (async only)
438+    -  ** Cancelled Requests** : Handle ` AbortError `  when using AbortController cancellation (async only)
439+    -  ** Mixed Patterns** : You can use both ` sendRequest() `  and ` sendRequestAsync() `  in the same code
346440
347441### Debugging Tips  
348442
@@ -354,6 +448,10 @@ int8[] data
354448
355449-  Both examples use the standard rclnodejs initialization pattern
356450-  The service server runs continuously until manually terminated
357- -  The client performs a single request-response cycle then exits
451+ -  The traditional client performs a single request-response cycle then exits
452+ -  The async client demonstrates multiple patterns and then exits
453+ -  ** New async/await support** : Use ` sendRequestAsync() `  for modern Promise-based patterns
454+ -  ** Full backward compatibility** : Existing ` sendRequest() `  callback-based code continues to work unchanged
455+ -  ** TypeScript support** : Full type safety available for async methods
358456-  Service introspection is only available in ROS 2 Iron and later distributions
359457-  BigInt is required for integer message fields to maintain precision
0 commit comments