JavaScript setTimeout 不反映更新的变量值

问题描述 投票:0回答:1

我遇到了

setTimeout
函数的问题,它似乎没有反映变量的更新值。

这是我的代码的简化版本:

const handleProcessError = (processName, process) => {
    let responseTimeout;
    let responseAlreadySent = false;

    const sendResponse = (status, message, scan_id, scantype, error) => {
        if (!responseAlreadySent) {
            responseAlreadySent = true;
            clearTimeout(responseTimeout);
            if (status === 'Success') {
                console.log('Sending success response', responseAlreadySent);
                res.status(200).json({ status, message });
            } else {
                console.log('Sending error response', responseAlreadySent);
                res.status(500).json({ status, message });
                revertScanAndThrowError(error, processName);
            }
        } else {
            console.log('Response already sent, skipping');
        }
    };

    responseTimeout = setTimeout(() => {
        sendResponse('Success', 'The scan started', inc_val, scantype);
    }, 5000);
    
    let errorOutput = '';
          
    process.stderr.on('data', (data: Buffer) => {
        errorOutput += data.toString();
    });

    process.on('exit', (code: number, signal: NodeJS.Signals) => {
        if (code !== 0) {
            sendResponse('Error', 'Failed to start the scan', null, null, new Error(`Process exited with code ${code}. Error output: ${errorOutput}`));
        } else {
            console.log(`${processName} process exited with code 0`);
        }
    });

    // Other event listeners and handlers...
};

在这段代码中,handleProcessError使用setTimeout设置了一个超时函数。当发生错误时,它会调用 sendResponse,这会将 responseAlreadySent 标志更新为 true。但是,即使标志已更新,超时函数仍然会执行,从而导致意外行为。

javascript node.js typescript settimeout
1个回答
0
投票

这是一个范围问题。每次运行 sendResponse 时,它都会看到它自己的

responseAlreadySent
版本。您可以通过在
handleProcessError
之外的范围内声明变量来解决此问题。这是显示此内容的简化版本

var responseAlreadySent = false;
const handleProcessError = (processName, process) => {
    let responseTimeout;

    const sendResponse = () => {
        console.log(responseAlreadySent);
        
        if (!responseAlreadySent) {
            responseAlreadySent = true;
            clearTimeout(responseTimeout);

            console.log('Sending response');
        } else {
            console.log('Response already sent, skipping');
        }
    };

    responseTimeout = setTimeout(() => {
        sendResponse();
    }, 5000);
    
    // Other event listeners and handlers...
};
© www.soinside.com 2019 - 2024. All rights reserved.