Javascript:如何检查异步操作是否仍在挂起/正在进行中?

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

我想知道是否有可能以某种方式检查 Javascript 中的异步操作是否仍在等待中.. 因为我正在调用特定的数据库请求 URL... 虽然数据库调用仍在进行中,但我想停止任何其他传入的数据库调用(这意味着停止对该 URL 以防数据库请求仍未决)。 这有可能吗?

因为数据库调用最多需要几分钟,而且我不想在第一个数据库调用仍在进行时启动另一个数据库调用。问题是,我不知道如何检查调用是否正确已经开始并且仍在进行中,因为只有当流程已经完成时,响应才会出现在 .then() 子句之后。

这是我的数据库调用函数:

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

        writeMessageObject = checkDocuments(...);

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

这是我的 URL/Route 使用 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);
            };

    } 
});

嗯,我在这里找到了一个解决方法: https://ourcodeworld.com/articles/read/317/how-to-check-if-a-javascript-promise-has-been-fulfilled-rejected-or-resolved

所以我编写了该函数来检查 promise stati,但我仍然想知道是否无法以某种方式查询静态 promise 属性以获取其实际状态 ;) (但奇怪的是,我在网上没有找到。

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;    
}

所以我针对请求修复了函数:

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);
            };

    } 
});

如果操作仍然是 运行,您需要尝试添加 node.js like global.dbCallState 标记。

这个 global var one 适用于所有模块。 不要像 global = new Object(); 那样更改此对象,但您可以使用子字段的。

https://nodejs.org/api/globals.html

您可以在另一个模块中更改它,例如 global.dbCallState = false

这不是最佳解决方案,但可以提供帮助。


但我不知道,为什么你只想要一个连接。在node.js

中屏蔽I/O不好解决