Skip to content Skip to sidebar Skip to footer

Incorporating Async Actions, Promise.then() And Recursive SetTimeout Whilst Avoiding "deferred Antipattern"

I have been reading up on methods to implement a polling function and found a great article on https://davidwalsh.name/javascript-polling. Now using a setTimeout rather than setInt

Solution 1:

I think you're almost there, it seems you're just struggling with the asynchronous nature of javascript. Using promises is definitely the way to go here and understanding how to chain them together is key to implementing your use case.

I would start by implementing a single method that wraps setTimeout to simplify things down.

function delay(millis) {
    return new Promise((resolve) => setTimeout(resolve, millis));
}

Then you can re-implement the "API" methods using the delay function.

const userIdApi = () => {
    return delay(2000).then(() => "uid123");
};

// Make userId an argument to this method (like pollDatabase) so we don't need to get it twice.
const startProcessingTaskApi = (userId) => {
    return delay(2000).then(() => "Task submitted");
};

const pollDatabase = (userId) => {
    return delay(2000).then(() => true);
};

You can continue polling the database by simply chaining another promise in the chain when your condition is not met.

function pollUntilComplete(userId) {
    return pollDatabase(userId).then((result) => {
        if (!result) {
            // Result is not ready yet, chain another database polling promise.
            return pollUntilComplete(userId);
        }
    });
}

Then you can put everything together to implement your use case.

userIdApi().then((userId) => {
    // Add task processing to the promise chain.
    return startProcessingTaskApi(userId).then(() => {
        // Add database polling to the promise chain.
        return pollUntilComplete(userId);
    });
}).then(() => {
    // Everything is done at this point.
    console.log('done');
}).catch((err) => {
    // An error occurred at some point in the promise chain.
    console.error(err);
});

Solution 2:

This becomes a lot easier if you're able to actually use the async and await keywords.

Using the same delay function as in Jake's answer:

async function doItAll(userID) {
    await startTaskProcessingApi(userID);
    while (true) {
        if (await pollDatabase(userID)) break;
    }
}

Post a Comment for "Incorporating Async Actions, Promise.then() And Recursive SetTimeout Whilst Avoiding "deferred Antipattern""