Как исправить кучу JavaScript из памяти

#javascript #node.js #actions-on-google

#javascript #node.js #действия в Google

Вопрос:

введите описание изображения здесьвведите описание изображения здесьЯ работаю с консолью действий Google. Здесь у меня есть веб-хук, смотрите код ниже. Теперь, когда я запускаю это, я получаю следующую ошибку:

НЕУСТРАНИМАЯ ОШИБКА: сбой выделения CALL_AND_RETRY_LAST — JavaScript не хватает памяти

 const {
conversation,
Simple,
Canvas,
Card,
Link,
Suggestion,
Image,
} = require('@assistant/conversation');
const functions = require('firebase-functions');    
const app = conversation();

const categories = {
    nhgooi: {
        antwoorden: [
        'Ze willen dat pedojager onmiddelijk stoppen.',
        'Ze willen dat pedojagers zo doorgaan.',
        'Ze willen dat pedojagers pedofielen nog harder aanpakken.',
        'Ze willen dat pedojagers pedofielen blijven zoeken maar ze minder hard aanpakken.',
        ],
        vraag: [
            "Wat wilt de politie dat pedojagers doen?"
        ],
        image: {
        url: "https://storage.googleapis.com/gweb-uniblog-publish-prod/images/"  
            "Search_GSA.2e16d0ba.fill-300x300.png",
        alt: 'Google app logo',
        },
    },
    };


function randomarray(i_array, antwoorden, category){ //make an array with items in random order
    while (i_array.length > 0){
    i = Math.floor(Math.random() * i_array.length);
    var index = i - 1;
    antwoorden.push(categories[category].antwoorden[index]);
    delete i_array[index];
    }
    return antwoorden;
}

app.handle('NieuwsQuiz_Vragen', (conv) => {
    var antwoorden = [];
    var i_array = [0, 1, 2, 3];
    const category = conv.scene.slots.vraag_categorie.value; //gekozen categorie (regio)
    const vraag = categories[category].vraag[0];
    const antwoorden_shuffled = randomarray(i_array, antwoorden, category);
    const antwoorden_string = antwoorden_shuffled.toString();
    const image = categories[category].image[0];

    const prefix = `Jij hebt gekozen voor vragen uit ${category}, laten we snel beginnen!`;
    conv.add(prefix);
    const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
    if (supportsRichResponse) {
        conv.add(new Card({
        title: vraag,
        subtitle: antwoorden_string,
        image: new Image(image),
        button: new Link({
            name: 'Learn more',
            open: {
            url: 'https://www.google.com/about/'
            }
        })
        }));
    }
    // conv.add(new Simple({
    //     speech: `${prefix} ${vraag}`,
    //     text: vraag,
    // }));

    // for( let i=0 ; i <= antwoorden.length ; i   ) {
    //     conv.add(new Suggestion({title: antwoorden[i]})); 
    // }
    //conv.add(new Suggestion({title: 'Quit'}));
});

exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
 

Кто-нибудь знает, как это исправить? Я рассмотрел другие вопросы по этой проблеме в Stack, но все эти решения должны были использоваться в терминале, а не в webhook.

Комментарии:

1. Попробуйте увеличить лимит памяти с помощью флага —max_old_space_size.

2. github.com/endel/increase-memory-limit/issues/19

3. @kg99 спасибо! Я добавил его в свой код, но он выдает 2 ошибки:

4. — неожиданные ПАРАМЕТРЫ УЗЛА

5. — неправильное назначение // (для знака =)

Ответ №1:

Исключение ООМ, как правило, не должно возникать в вашем коде, поскольку выделение памяти по умолчанию составляет 256 МБ или 512 МБ, что намного больше, чем вам нужно. Это заставило меня поверить, что у вас утечка памяти в вашем коде.

Просматривая, мне кажется, что randomarray это происходит, когда вы выполняете манипуляции с массивом в цикле while, оба из которых могут быть потенциально бесконечными, если вы не будете осторожны.

Я скопировал вашу функцию randomarray ниже:

 // make an array with items in random order
function randomarray(i_array, antwoorden, category){
    while (i_array.length > 0){
      i = Math.floor(Math.random() * i_array.length);
      var index = i - 1;
      antwoorden.push(categories[category].antwoorden[index]);
      delete i_array[index];
    }
    return antwoorden;
}
 

Основываясь на вашем комментарии, я полагаю, что вам нужна функция перетасовки массива.
Он используется здесь:

 var antwoorden = [];
var i_array = [0, 1, 2, 3];
const category = conv.scene.slots.vraag_categorie.value; //gekozen categorie (regio)
const vraag = categories[category].vraag[0];
const antwoorden_shuffled = randomarray(i_array, antwoorden, category);
 

Если я сам воспроизведу эту функцию и добавлю несколько строк, чтобы посмотреть, что произойдет, я получу это:

 i_array: [,1,2,3] (Length 4)
i_array: [,,2,3] (Length 4)
i_array: [,,,3] (Length 4)
i_array: [,,,3] (Length 4)
i_array: [,,,3] (Length 4)
...
 

Кажется, что это бесконечно повторяется, каждый раз добавляя один из ваших ответов в массив. Через некоторое время массив станет слишком большим и произойдет сбой.

Почему это происходит? Похоже, в вашей реализации есть несколько ошибок.

  1. У вас есть index переменная, для которой установлено значение i - 1 . Это неверно, поскольку алгоритм Math.floor(Math.random() * i_array.length) будет корректно возвращать действительный индекс каждый раз. Ваша реализация index всегда будет пропускать последний элемент в массиве, в результате чего цикл будет продолжаться вечно.
  2. delete Команда удалит значение в определенном индексе, но не изменит длину массива. Скорее всего, ваш массив будет иметь значение [empty, empty, empty, empty] , массив, который по-прежнему имеет длину 4. Пока вы вычисляете, пока длина не будет равна 0, этот цикл никогда не закончится. Использование splice метода удалит элемент из массива и уменьшит длину массива.
 function randomarray(i_array, antwoorden, category){
    while (i_array.length > 0) {
      i = Math.floor(Math.random() * i_array.length);
      antwoorden.push(categories[category].antwoorden[i]);
      i_array.splice(i, 1)
    }
    return antwoorden;
}
 

Вы можете внести эти исправления или, в качестве альтернативы, рассмотреть возможность использования готового модуля npm для перетасовки массивов.