Javscript для цикла, который добавляет даты в массив, замораживает страницу на некоторых компьютерах - PullRequest
0 голосов
/ 29 октября 2019

У меня странная проблема при запуске одной из созданных мной страниц ASP. Я протестировал веб-страницу на нескольких компьютерах, и только некоторые из них могут правильно отображать страницу. Для большинства компьютеров, на которых я тестировал, страница полностью загружена и полностью функциональна. Для некоторых людей страница зависает, и Chrome показывает, что она ожидает кэш или сервер - все поля ввода не активируются. С другой стороны, страница отлично работает для них на Edge. Есть один компьютер, на котором страница не работает ни в Chrome, ни в Edge. Каждый ПК имеет одну и ту же версию Windows 10, одну и ту же версию Chrome и Edge.

После комментирования некоторого кода я обнаружил, что есть один цикл for, который вызывает сбои на некоторых компьютерах. По сути, я пытаюсь отобразить некоторые данные для определенного диапазона дат. Если в этом диапазоне нет данных для даты, обычно она отсутствует, поэтому я добавляю ее в цикл for ниже. и позже присвоение этой дате значения 0, чтобы у меня была таблица с хорошим макетом с непрерывными датами.

// Checking if there are no missing dates in the date range. This could happen if the date doesn't exist in the SQL database.
for (var i = 0; i < dateArray.length - 1; i++) {
    // Checking if the next date is only incremented by 1
    var currentDate = GetDate(dateArray[i]);
    var nextDate = GetDate(dateArray[i + 1]);
    var shouldBeNextDate = GetNextDayDate(currentDate);

    // Adding the date that is missing. If the date won't be found later the quantities will be set to 0.
    if (convertDateToString(shouldBeNextDate) != convertDateToString(nextDate)) {
        dateArray.splice(i + 1, 0, convertDateToString(shouldBeNextDate));
    }
}

// Returns Date() from string
function GetDate(date){
    var numbers = date.match(/\d+/g);
    return new Date(numbers[2], numbers[1] - 1, numbers[0]);
}

// Returns the next day of the Date() passed as an argument
function GetNextDayDate(date){
    var numbers = convertDateToString(date).match(/\d+/g);
    return new Date(numbers[2], numbers[1] - 1, parseInt(numbers[0]) + 1);
}

// Returns Date() converted to string 
function convertDateToString(strDate){
    // Setting to MM/dd/YYYY format
    strDate = new Date(strDate).toLocaleDateString();
    var firstDash = strDate.indexOf("/");
    var secondDash = strDate.indexOf("/", firstDash + 1);
    var tempMM = strDate.substr(0, firstDash);
    var tempDD = strDate.substr(firstDash + 1, secondDash - firstDash - 1);
    var tempYYYY = strDate.substr(strDate.length - 4, 4);

    return tempDD + "/" + tempMM + "/" + tempYYYY;
}

Когда цикл for был закомментирован, страница успешно загружена для всех. Есть идеи, что может быть причиной проблем? Я скучаю по чему-то прямому?

1 Ответ

2 голосов
/ 30 октября 2019

Проблема с этим кодом:

strDate = new Date(strDate).toLocaleDateString();

Несмотря на то, что в комментариях вы указали, что это даст строковое представление в формате MM / dd / YYYY, это не гарантируется. Как описано в mdn (курсив мой):

Метод toLocaleDateString() возвращает строку с чувствительным к языку представлением части даты этой даты,

Например, когда я набираю следующее в консоли моего браузера:

new Date().toLocaleDateString()

... тогда в FireFox я получаю:

"29.10.2009 "

- это то, что вы ожидаете, но в Chrome я получаю:

" 29-10-2019 "

По-видимому, существует некоторая путаница с тем, что на самом деле является моей локалью. Однако важно то, что неверно принимать какой-либо формат (если вы не передаете аргументы toLocaleDateString, которые делают его независимым от вашего текущего языкового стандарта).

Итак, представьте, что вы передаете объект Date 29.10.2009на convertDateToString: в последнем случае он даже не найдет косые черты в строке, возвращаемой .toLocaleDateString, и поэтому возвращаемая строка будет "// 2019". Когда GetNextDayDate пытается сделать из этого объект Date, он возвращает недопустимую Date.

Следовательно, условие if в вашем цикле всегда будет истинным, и новая запись будет вставлена ​​в ваш цикл. массив, что делает длину вашего массива больше, и поэтому цикл никогда не заканчивается.

Решение состоит в том, чтобы выполнять преобразование даты в строку только тогда, когда это действительно необходимо, а когда вы делаете, использовать методы Date дляизвлеките части даты, а не toLocaleDateString.

Вот исправленный код:

for (var i = 0; i < dateArray.length - 1; i++) {
    var currentDate = GetDate(dateArray[i]);
    var nextDate = GetDate(dateArray[i + 1]);
    var shouldBeNextDate = GetNextDayDate(currentDate);

    // No need to convert to String
    if (shouldBeNextDate < nextDate) {
        dateArray.splice(i + 1, 0, convertDateToString(shouldBeNextDate));
    }
}
console.log(dateArray);

function GetDate(date){
    var numbers = date.match(/\d+/g);
    return new Date(numbers[2], numbers[1] - 1, numbers[0]);
}

function GetNextDayDate(date) { // Don't convert to string here.
    date = new Date(date); // clone the date
    date.setDate(date.getDate() + 1); // add one day to it
    return date;
}

function convertDateToString(date) {
    // Get the date parts directly
    let tempMM = date.getMonth() + 1;
    let tempDD = date.getDate();
    let tempYYYY = date.getFullYear();

    // Pad with zeroes where needed
    return (tempDD + "/" + tempMM + "/" + tempYYYY).replace(/\b\d\b/g, "0$&");
}
...