2

我想知道是否有可能以某种方式检查 Javascript 中的异步操作是否仍处于挂起状态。因为我正在对调用特定 URL 进行数据库请求...虽然 db 调用仍在进行中,但我想停止任何其他传入的 db-calls(这意味着,如果 db-request 仍处于挂起状态,则停止对该 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 Call 函数,带有 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);
            };

    } 
});
4

2 回答 2

0

嗯,我在这里找到了一个解决方法: https ://ourcodeworld.com/articles/read/317/how-to-check-if-a-javascript-promise-has-been-fulfill-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);
            };

    } 
});
于 2019-03-05T12:38:56.157 回答
0

global.dbCallState如果操作仍在运行,您需要尝试添加 node.js 之类的标志。

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

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

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

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


但我不知道,为什么你只想要一个连接。在 node.js 中阻止 I/O 并不是一个好的解决方案

于 2019-03-05T12:42:05.143 回答