Context in JavaScript

Here’s the translation of the Go code to JavaScript, formatted in Markdown suitable for Hugo:

In this example, we’ll look at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of asynchronous operations and cancellation in JavaScript. We’ll use the express framework for creating the server and node-abort-controller for handling cancellation.

First, let’s set up our dependencies:

const express = require('express');
const { AbortController } = require('node-abort-controller');

Now, let’s define our request handler:

function hello(req, res) {
    console.log("server: hello handler started");

    // Create an AbortController for this request
    const controller = new AbortController();
    const { signal } = controller;

    // Simulate some work
    const timer = setTimeout(() => {
        res.send('hello\n');
        console.log("server: hello handler ended");
    }, 10000);

    // Listen for client disconnection
    req.on('close', () => {
        clearTimeout(timer);
        controller.abort();
        console.log("server: request aborted");
        console.log("server: hello handler ended");
    });

    // Use the AbortSignal to cancel the operation if needed
    signal.addEventListener('abort', () => {
        clearTimeout(timer);
        if (!res.headersSent) {
            res.status(500).send('Internal Server Error');
        }
    });
}

In this handler:

  1. We create an AbortController for each request. This is similar to the context.Context in the original example.
  2. We use setTimeout to simulate a long-running operation.
  3. We listen for the ‘close’ event on the request, which is emitted when the client disconnects.
  4. We use the AbortSignal to handle cancellation, similar to how ctx.Done() is used in the original.

Now, let’s set up our server:

const app = express();
app.get('/hello', hello);

const server = app.listen(8090, () => {
    console.log('Server is running on port 8090');
});

To run this server:

$ node server.js
Server is running on port 8090

You can then simulate a client request to /hello, and interrupt it:

$ curl localhost:8090/hello
server: hello handler started
^C
server: request aborted
server: hello handler ended

In this JavaScript version, we’ve replicated the behavior of the original Go example using Express and AbortController. The AbortController provides similar functionality to Go’s context.Context, allowing us to handle cancellation in a clean way.

Note that JavaScript’s asynchronous nature and event-driven model provide a different approach to handling concurrency compared to Go’s goroutines, but the end result is similar.