Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
错误:调用和重试上次分配失败-Javascript堆内存不足_Javascript_Memory_Memory Management_Memory Leaks - Fatal编程技术网

错误:调用和重试上次分配失败-Javascript堆内存不足

错误:调用和重试上次分配失败-Javascript堆内存不足,javascript,memory,memory-management,memory-leaks,Javascript,Memory,Memory Management,Memory Leaks,我正在学习NodeJS和Javascript。我正试图开发一个应用程序来阅读和下载漫画 首先我想建立一个数据库。这就是我遇到的问题。 当我在内存为4GB的服务器上运行我的程序时(用以填充我的数据库),我得到了内存不足的致命错误Javascript堆 当我用8GB内存在本地计算机上运行相同的程序时,一切都正常工作 这是我用漫画章节填充数据库的代码 function insertChapters(callback){ sql_selectAll("Mangas", function (se

我正在学习NodeJS和Javascript。我正试图开发一个应用程序来阅读和下载漫画

首先我想建立一个数据库。这就是我遇到的问题。 当我在内存为4GB的服务器上运行我的程序时(用以填充我的数据库),我得到了内存不足的致命错误Javascript堆

当我用8GB内存在本地计算机上运行相同的程序时,一切都正常工作

这是我用漫画章节填充数据库的代码

function insertChapters(callback){

    sql_selectAll("Mangas", function (selectError, selectResult) {
        if(!selectError){
            selectResult.forEach(function (mangaItem, mangaIndex) {
                gin.mangafox.chapters(mangaItem.Title)
                    .then(chapters =>{

                        chapters.forEach(function (chapterItem) {
                            var Chapter = {
                                Title: chapterItem.name,
                                NR: chapterItem.chap_number,
                                URL: chapterItem.src,
                                MangaID: mangaItem.MangaID,
                                MangaName: mangaItem.Title,
                                VolumeNR: chapterItem.volume
                            };
                            sql_insertInto("Chapters", Chapter, function (insertError, insertResult) {
                            if(!insertError){
                                var insertedChapter =
                                "------------------------------------------------------------------------\n" +
                                "  Added new Chapter: " + Chapter.NR + " For: " + mangaItem.Title + "\n" +
                                "------------------------------------------------------------------------\n";
                                callback(null,insertedChapter ,insertResult);
                            }
                            else{
                                if(insertError.code === "ER_DUP_ENTRY") {
                                    var dupEntry = "------------------------------------------------------------------------\n" +
                                                   "  Duplicate Entry: Chapter: " + Chapter.NR + " For: " + mangaItem.Title + "\n" +
                                                   "------------------------------------------------------------------------\n"

                                        callback(null, dupEntry, null);
                                    }
                                    else{
                                        callback(insertError, null, null);
                                    }
                                }
                            })
                        })

                    })
                    .catch(fetchChapterError => {
                        callback(fetchChapterError, null, null);
                    })
            })
        }
        else{
            callback(selectError, null, null);
        }
    });
}`
我真的不知道如何解决这个问题,因为我不确定问题是什么:

  • 问题仅仅是我的服务器中没有足够的RAM吗
  • 我的代码有问题吗?我是不是在某处泄露记忆
  • 我的代码可能需要那么多内存吗
  • 提前非常感谢你,我感谢你给我的一切帮助

    编辑:


    您正在同时为每个SQL结果调用mangafox端点,而不是一次调用一个端点或分块调用一个端点。你可以试着用这个。我不熟悉您正在使用的sql API,但假设方法
    sql\u selectAll
    sql\u insertInto
    在没有回调的情况下返回,您可以将函数重写为如下内容:

    async function insertChapters(callback) {
        try {
            const mangas = await sql_selectAll("Mangas");
            for (const mangaItem of mangas) {
                const chapters = await gin.mangafox.chapters(mangaItem.Title);
                for (const chapterItem of chapters) {
                    const Chapter = {
                        Title: chapterItem.name,
                        NR: chapterItem.chap_number,
                        URL: chapterItem.src,
                        MangaID: mangaItem.MangaID,
                        MangaName: mangaItem.Title,
                        VolumeNR: chapterItem.volume
                    };
                    try {
                        const insertResult = await sql_insertInto("Chapters", Chapter);
                        const insertedChapter =
                        "------------------------------------------------------------------------\n" +
                        "  Added new Chapter: " + Chapter.NR + " For: " + mangaItem.Title + "\n" +
                        "------------------------------------------------------------------------\n";
                        callback(null, insertedChapter, insertResult);
                    } catch (error) {
                        if (error.code === "ER_DUP_ENTRY") {
                            const dupEntry = "------------------------------------------------------------------------\n" +
                                           "  Duplicate Entry: Chapter: " + Chapter.NR + " For: " + mangaItem.Title + "\n" +
                                           "------------------------------------------------------------------------\n";
                            callback(null, dupEntry, null);
                        } else {
                            throw error;
                        }
                    }
                }
            }
        } catch (error) {
            callback(error, null, null);
        }
    }
    
    请注意
    await
    关键字-这些关键字在
    async function
    s中是允许的,本质上是告诉JS引擎暂停异步函数的执行并执行其他操作,直到等待的承诺得到解决

    还请注意,在使用
    wait
    关键字处理承诺时,可以使用常规的老式
    try
    /
    catch
    块!我没有做任何特殊的操作来处理
    fetchchapterror
    ,因为它将由最外层的
    catch
    块处理!另外,对于插入错误,如果它不是重复的条目,我们可以重新显示该错误,并让最外层的catch块也捕获该错误

    如果SQL函数不返回承诺,那么在节点版本8(最新版本)上,可以使用
    util.promisify

    const util = require('util');
    sql_selectAll = util.promisify(sql_selectAll);
    

    如果您没有使用Node 8,那么您可以使用另一个
    promisify
    实现(例如,签出),或者您可以非常轻松地编写自己的实现(阅读关于promises的MDN文章)。

    初始SQL查询返回了多少个结果?另外,需要注意的是,您正在为SQL中的每个结果立即调用
    gin.mangafox.chapters
    端点,然后等待所有结果返回。这就是JS中异步编程的工作原理——代码在异步调用等待时保持运行。当您调用
    forEach
    时,它将立即为每个项运行给定的函数,而不等待在调用之间返回任何异步结果。如果数据库中有数百个漫画,则同时执行数百个API调用。初始查询返回大约19000个结果,这些19000个结果中的每一个平均有15-20个章节。有没有更好的更方便记忆的方法?我仍在努力学习异步编程。感谢您的快速回复!是的,因此您同时对mangafox API端点执行19000个请求。内存不足是因为程序试图跟踪太多的异步请求,而不是一次一个或分块执行。你有没有研究过JS的异步/等待特性?另外,您在SQL调用中使用了什么?我不认识像
    sql\u selectAll
    sql\u insertInto
    这样的方法。如果这些方法返回承诺,我可以向您展示如何使用async/await构造函数。他们目前不兑现承诺。但我可以改变它。但是我该怎么做呢?我不熟悉async/Wait,但我对一切都很开放。你能告诉我你的想法吗?:)非常感谢你的帮助!!!看看我的答案,我想这会有点帮助。它一次调用一个端点,而不是成批调用,因此可能需要很长时间才能运行。一旦您理解了一次一个的代码,我将让您自己决定如何进行批处理。(提示:请阅读关于Thanke you的MDN文章。我会尝试一下。您非常有帮助!@calgara12不客气。另外请注意,
    async function
    s会自动返回,因此最好去掉函数的回调参数,使用
    insertChapters()。然后(successCallback)。catch(errorCallback)
    。或者,您可以使用另一个异步函数调用
    尝试{wait insertChapters()}catch(error){/*…*/}
    。但是,在代码的顶层,您可能需要使用
    然后
    /
    捕获
    一次,因为您只能在异步函数中使用
    等待
    ,并且希望能够处理该异步函数返回的承诺。
    const util = require('util');
    sql_selectAll = util.promisify(sql_selectAll);