Использование обещаний внутри цикла for - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь перебрать диапазон дат, чтобы вернуть лучшую песню для каждой даты. Так что у меня есть для l oop. В этом случае для l oop вызывается функция, которая просматривает мою базу данных на предмет лучшей песни. Поэтому я завернул его в обещание, чтобы оно выдерживало l oop, но этот подход, похоже, тоже не работает. Может кто-нибудь объяснить лучший подход для решения этой проблемы.

app.post('/getDate', function (req, res) {
      this.tracks = [];
      let until = new Date(req.body.dateToOutput);
      for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
            date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
            console.log('date', date);
            new Promise(function (resolve, reject) {
                  getDate(date).then(() => {
                        resolve();
                  })
            });
      }
      console.log(this.tracks);
});
function getDate(date) {
      return new Promise(function (resolve, reject) {
            Track.find({ Date: date }, function (err, track) {
                  if (!err) {
                        console.log(track);
                        this.tracks.push(track);
                        resolve();
                  }
                  else {
                        reject();
                  }
            }).sort({ Streams: -1 }).limit(1);
      });
}

1 Ответ

1 голос
/ 15 апреля 2020

Я думаю, что обещание не выполняется, а также я думаю, что вы указываете на неопределенный объект в вашей функции getDate, и for l oop не ожидает обещания, которое будет выполнено или отклонено. посмотрите это:

new Promise(function (resolve, reject) {
    getDate(date).then(() => {
        resolve();
    })
});

вы создаете новое обещание, но вы никогда не выполняете это обещание.

также в функции getDate вы указываете на объект, который не существует в его контекст:

this.tracks.push(track);

Это приведет к ошибкам, поскольку this.tracks не является частью getDate Функция является частью анонимной функции, которая вызывается методом app.post.

поэтому вместо непосредственного нажатия на this.tracks вы должны вернуть сам трек:

if (!err) {
    console.log(track);
    resolve(track);
}

, затем вы должны использовать asyn c - ждите, чтобы обязать l oop для создания приостанавливать выполнение обещания до тех пор, пока оно не будет разрешено или отклонено, поэтому ваша анонимная функция теперь должна быть анонимной функцией asyn c, чтобы использовать await, также вам не нужна оболочка обещания внутри другого обещания, я имею в виду вас это не нужно:

new Promise(function (resolve, reject) {
    getDate(date).then(() => {
        resolve();
    })
});

Вам нужно только это:

getDate(date).then(() => {
   resolve();
})

, потому что функция getDate () сама возвращает обещание.

Так вот как ваш код выглядит после создания всех этих чан ges:

const response = app.post('/getDate', async function (req, res) {
      this.tracks = [];

      let until = new Date(req.body.dateToOutput);
      for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
            date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
            console.log('date', date);
            const ctrack = await getDate(date);
            this.tracks.push(ctrack);
      }

      console.log(this.tracks);
      return this.tracks;
});

function getDate(date) {
      return new Promise(function (resolve, reject) {
            Track.find({ Date: date }, function (err, track) {
                  if (!err) {
                        console.log(track);
                        resolve(track);
                  }
                  else {
                        reject();
                  }
            }).sort({ Streams: -1 }).limit(1);
      });
}

И теперь, когда у вас есть ответ в качестве обещания, потому что функция asyn c возвращает обещание ... вы можете затем его перехватить и использовать ответ:

response.then(trackList =>{
   console.log(trackList);
}).catch(()=>{
   console.error("something went wrong...!");
})
...