如何减少 Node.js 应用程序使用的内存量?

How can I reduce the amount of memory my Node.js application uses?

总的来说,我对 Node.js 和 Javascript 还很陌生。 (我也是 Whosebug 的新手!)最近,我写了一个 Node.js 应用程序,它占用了太多内存。我读到 setTimeout() 可能会导致内存泄漏,而我的代码恰好使用了它。 这是我的代码:

var Scratch = require('scratch-api');
const fetch = require('node-fetch');
require('dotenv').config()
Scratch.UserSession.create(process.env.SCRATCH_USERNAME, process.env.SCRATCH_PASSWORD, function (err, user) {
    user.cloudSession(419697811, function (err, cloud) {
        let code = ["", "", "", "", "", "", "", "", "", "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "-", ".", " ", "_"]
        var encoded,
            idx,
            letter_num,
            value
        function decode(encoded) {
            letter_num = 0
            value = ""
            do {
                idx = encoded.charAt(letter_num) + encoded.charAt(letter_num + 1)
                letter_num = letter_num + 2
                if (Number(idx) < 1) { //evaluates it as a number rather than a string
                    break
                }
                value = value + code[Number(idx)]
            } while (Number(idx) >= 1)
            return value
        }
        function encode(val) {
            temp = "" //so it concatenates strings rather than adding numbers
            letter_num = 1
            for (letter_num = 0; letter_num < val.length; letter_num++) {
                temp += code.indexOf(val.charAt(letter_num))
            }
            temp += "00" //otherwise it would evaluate to 0
            return temp
        }
        
        var idle_counter = 0

        function timeout() {
            setTimeout(function () {
                var cloud_check = cloud.get('☁ checkMessage')
                if (cloud_check > 0){
                    if (cloud_check == 1){
                        cloud.set('☁ checkMessage', 2)
                    } else if (cloud_check == 2){
                        idle_counter++
                        if (idle_counter > 5){
                            cloud.set('☁ checkMessage', 0)
                            idle_counter = 0
                        }
                    } else if (cloud_check == 3){
                        if (cloud.get('☁ message') != 0){
                            var username = decode(cloud.get('☁ message'))
                            fetch('https://api.scratch.mit.edu/users/' + username + '/messages/count')
                            .then(res => res.json())
                            .then(data => {
                                var message = ""
                                if (data.code == null) {
                                    message = encode("success." + data.count)
                                    console.log("SUCCESS - Successfully retrieved the message count (" + data.count + ") for the user " + username + "!")
                                } else {
                                    message = encode("error.user not found")
                                    console.log("ERROR - The user " + username + " could not be found!")
                                }
                                cloud.set('☁ message', message)
                                cloud.set('☁ checkMessage', 4)
                                idle_counter = 0
                            })
                        }
                    } else {
                        idle_counter++
                        if (idle_counter > 5){
                            cloud.set('☁ checkMessage', 0)
                            idle_counter = 0
                        }
                    }
                }
                timeout();
            }, 2000);
        }
        timeout() //a loop
    });
});

注:这只是我为了连接Scratch而写的练习代码。非常感谢任何帮助。谢谢!

您一直在调用超时,而没有等待 cloud_check 3 if 语句中的 fetch 完成。我会稍微更改代码以使其更具可读性并等待此提取完成,因为您似乎依赖于来自该调用的信息来设置 cloud_check 的下一个状态。如果该调用花费的时间比您的超时时间长,那么您将堆积很多函数。

我会将代码分解为三个函数

getCount --> 从 api 中获取计数 updateChecks --> 更新云检查 超时 --> 运行你的超时循环

下面是一些帮助您入门的清理工作。但一定要看看如何使代码更具可读性和可重用性。

       async function getCount(username) {
             var res = await fetch(`https://api.scratch.mit.edu/users/${username}/messages/count`);
              var data = res.json()
              if(!data.code) {
                  return data.count;
              }
              throw new Error(`ERROR - The user ${username} could not be found!`)
        }

        async function updateChecks() {
            var cloud_check = cloud.get('☁ checkMessage')
            if (cloud_check > 0){
                if (cloud_check == 1){
                    cloud.set('☁ checkMessage', 2)
                } else if (cloud_check == 2){
                    idle_counter++
                    if (idle_counter > 5){
                        cloud.set('☁ checkMessage', 0)
                        idle_counter = 0
                    }
                } else if (cloud_check == 3){
                    var username = decode(cloud.get('☁ message'))
                    try {
                        var count = await getCount(username)
                        message = encode(`success.${count}`)
                        console.log(`SUCCESS - Successfully retrieved the message count (${count}) for the user ${username} !`)
                    } catch(e) {
                        message = encode("error.user not found")
                        console.log(e.message)
                    }
                    cloud.set('☁ message', message)
                    cloud.set('☁ checkMessage', 4)
                    idle_counter = 0
                } else {
                    idle_counter++
                    if (idle_counter > 5){
                        cloud.set('☁ checkMessage', 0)
                        idle_counter = 0
                    }
                }
            }
        }

        async function timeout() {
            setTimeout(async () => {
                await updateStates();
                timeout();
            }, 2000);
        }