Переменные, изменяющиеся в цикле

#javascript #node.js #json

#javascript #node.js #json

Вопрос:

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

 Promise.all(promisses.map(o => API.functionName(o))).then((p) => {
    var i = startingDate;
    p.forEach(res =>{
        res.forEach(function(value) {
            rankExport.push({
                "teamName" : value.team.name,
                "teamId": value.team.id,
                "position" : value.place,
                "points" : value.points,
                "posChange" : value.change,
                "rankDay" : i.getDate(),
                "rankMonth" : i.getMonth()   1,
                "rankYear" : i.getFullYear(),
                "date" : i,
            });
        });
        i = add_weeks(i,1)
    });
    saveRankings(rankExport, i);
})
  

Это функция add_weeks:

 function add_weeks(date, n)  {
    return new Date(date.setDate(date.getDate()   (n * 7)));      
};
  

Одной из ключевых точек данных является дата, которую я сохраняю в массиве в виде дня, месяца, года и полной даты.

Проблема в том, что это результат, который я получаю:

 [
  {
    teamName: 'Team',
    teamId: 6665,
    position: 1,
    points: 1000,
    posChange: 0,
    rankDay: 27,
    rankMonth: 1,
    rankYear: 2020,
    date: 2020-02-03T03:00:00.000Z
  },
  

Сразу возникают две проблемы:

1- Есть две разные даты: 27/01/2020 и 03/02/2020, которые разделены неделей. Но почему? Они поступают из одной и той же переменной (i).

2- Даты сдвинуты на неделю (должно быть startingDate = 20/01/2020), что сбивает с толку, учитывая, что моя формула add_weeks должна выполняться после циклов, поскольку они не являются асинхронными, верно?

Помогите! Спасибо =)

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

1. Следуйте вашей логике, когда именно и сколько раз вы ожидаете вызова add_weeks()? Из вашего вопроса вообще невозможно сказать, почему у вас есть функция add_weeks(), и вы не говорите, каково ее использование или когда вы ожидаете, что она будет вызвана или почему. Также просто примечание, но этот результат недействителен в формате JSON, потому что вокруг даты нет кавычек.

2. Привет, @JasonGoemaat. Это должно вызываться каждый раз, когда res.forEach завершает цикл, так как тогда мы будем получать следующие значения p, которые относятся к следующей неделе.

3. Запросы также по неделям? Если вы создаете один запрос в неделю, возможно, имеет смысл сохранить его как часть возвращаемого объекта. Т.е. «var dt = new Date(); var myPromise = request(‘/getdata/${dt}’).затем (response => ({dt, ответ}));`

Ответ №1:

Я предполагаю, что проблема в вашей функции add_weeks(), которая не показана. Если вы вызовете что-то вроде setYear() для своего объекта date, это изменит дату на месте. Держу пари, что ваша функция add_weeks() неправильно копирует дату. Смотрите этот код:

 var i = new Date();
var a = {date: i};
i = new Date();
var b = {date: i};
i.setYear(1999);
var c = {date: i};
console.log(JSON.stringify({ a, b, c }, null, 2));
  

Результат b также показывает 1999 год, потому что setYear() изменил дату:

 {
  "a": {
    "date": "2020-09-03T20:34:18.284Z"
  },
  "b": {
    "date": "1999-09-03T20:34:18.284Z"
  },
  "c": {
    "date": "1999-09-03T20:34:18.284Z"
  }
}
  

Чтобы исправить это, в вашей функции add_weeks() создайте новую дату, ala:

 var dt = new Date();
var newDate = new Date(dt.getTime());
newDate.setYear(1999);
console.log(dt, newDate);
-- shows different dates
  

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

1. Добавлена функция в основной пост для контекста. РЕДАКТИРОВАТЬ: я вижу, возможно, формула add_weeks изменяет дату в i. Но почему даты отличаются, когда он нажимает на один и тот же i?

2. Это устранило проблему? Невозможно знать наверняка, это было мое лучшее предположение. Когда вы создаете объект для ввода, rankExport вы вызываете like getDate() , который возвращает день значения i в это время и устанавливает date значение i. Для следующего ответа, если вы добавите неделю к i , это изменит значение date для старых записей, потому что они будут ссылаться на ту же дату, но поскольку getDate() возвращено число, это значение будет таким, каким оно было, когда объект был создан и добавлен в rankExport

3. Помогает ли это или вы спрашиваете что-то еще с «Но почему даты отличаются, когда он нажимает на один и тот же i?»

4. date это ссылка на объект date, который является изменяемым, что означает, что он может изменяться. Это как если бы у вас был person объект с name . Если вы используете один и тот же объект, все они ссылаются на одно и то же в памяти, и изменение свойства в одном из них влияет на все места, на которые ссылается этот объект. скрипка

5. @MarianoMolina Вот обновленная скрипка, которая лучше показывает, что происходит. ‘FirstName’ отличается для каждого объекта, потому что это строковое значение, в то время как ‘name.first’ все ссылаются на объект с одним и тем же именем: fiddle