Search code examples
javascriptasynchronouspending-transition

Javascript: How to check if async operation is still pending / In progress?


I would like to know if it is somehow possible to check if an asynchronous operation in Javascript is still pending.. Because I am doing a database request on calling a specific URL... While the db call is still in progress, I want to stop any other incoming db-calls (which means, stop any further calls to that URL in case the db-request is still pending). Is that somehow possible?

Because the database call takes up to minutes, and I don't want to launch another database-call while the first is still in progress.. The problem is, I somehow cannot figure out how to check if the call has started and is still in progress, because the response comes only after the .then() clause when the process has already finished.

this is my db-call function:

const getWriteIndex = async () =>  {   
    return Promise.all(someFunction1, someFunction2...).then(...) {  

        writeMessageObject = checkDocuments(...);

        return Promise.resolve(writeMessageObject);       
       })).catch((err) => {           
           return Promise.reject(err);
       });
}

This is my URL/Route Call function with express:

router.get("/v1/...", someMiddleware(), async function(req,res,next) {    

    if (read_cached() && initialised_read) {
        res.setHeader('Content-Type', 'application/json');
        res.json(readmsg_obj);
    } else {    
        try {   
            //HOW CAN I CHECK HERE IF THE DB-CALL IS ALREADY IN PROGRESS?
                readmsg_obj.message = '';  
                getReadIndex().then((message) => {                       
                    initialised_read = true;
                    readmsg_obj = {...message};                
                    res.setHeader('Content-Type', 'application/json');
                    res.json(readmsg_obj);
                }).catch((reject) => {                  
                    logger.error(`/../... : ${reject}`);
                    initialised_read = false;
                    res.status(500).send(reject);
                });
            } catch(err)  {
                logger.error(`/v1/... : ${err}`);
                res.status(500).send(err);
            };

    } 
});

Solution

  • hmm I found a workaround here: https://ourcodeworld.com/articles/read/317/how-to-check-if-a-javascript-promise-has-been-fulfilled-rejected-or-resolved

    so I wrote that function to check for promise stati, but I am still wondering if it's not somehow possible to query for static promise properties to get their actual state ;) (but weirdly, I didn't find any on the web).

    const checkPendingRequest= (promise) => {
        if (promise.isResolved) return promise;    
            // Set initial state
            var isPending = true;
            var isRejected = false;
            var isFulfilled = false;
    
            // Observe the promise, saving the fulfillment in a closure scope.
            var result = promise.then(
                function(v) {
                    isFulfilled = true;
                    isPending = false;
                    return v; 
                }, 
                function(e) {
                    isRejected = true;
                    isPending = false;
                    throw e; 
                }
            );
    
            result.isFulfilled = function() { return isFulfilled; };
            result.isPending = function() { return isPending; };
            result.isRejected = function() { return isRejected; };
            return result;    
    }
    

    So I fixed my function for the request:

    router.get("/v1/...", someMiddleware(), async function(req,res,next) {    
    
        if (read_cached() && initialised_read) {
            res.setHeader('Content-Type', 'application/json');
            res.json(readmsg_obj);
        } else {    
            try {   
               readmsg_obj.message = '';  
    
                if ((dbQueryPromiseRead != null) && dbQueryPromiseRead.isPending()) {
                    logger.info(`Database request for Index-read is still pending!`);
                    return;
                }
    
                dbQueryPromiseRead =  checkPendingRequest(getReadIndex());
    
                dbQueryPromiseRead.then((message) => {  
                    initialised_read = true;
                    readmsg_obj = {...message};
    
                    res.setHeader('Content-Type', 'application/json');
                    res.json(readmsg_obj);
                    }).catch((reject) => {                  
                        logger.error(`/../... : ${reject}`);
                        initialised_read = false;
                        res.status(500).send(reject);
                    });
                } catch(err)  {
                    logger.error(`/v1/... : ${err}`);
                    res.status(500).send(err);
                };
    
        } 
    });