在 for 循环中使用 Promise

Posted

技术标签:

【中文标题】在 for 循环中使用 Promise【英文标题】:Using Promises within for loop 【发布时间】:2020-07-27 21:36:21 【问题描述】:

我正在尝试遍历一系列日期以返回每个日期的热门歌曲。所以我有一个 for 循环。在这个 for 循环中,调用了一个函数来查看我的数据库中的热门歌曲。因此,我将它包装在一个承诺中,以便它能够支撑 for 循环,但这种方法似乎也不起作用。有人可以解释一个更好的方法来解决这个问题。

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);
      );

【问题讨论】:

我认为您的问题已经得到解答,请查看:***.com/questions/40328932/… 另外你正在使用一个非常奇怪的 for 循环,它可能会中断或抛出一堆错误,为什么不使用数值?,我认为如果你不修复循环,我的答案将不起作用. 啊,我忘记了另一件事,在您的 getDate 函数中,您有 .sort(Streams: -1).limit(1),它永远不会反映在您的代码中,因为在Track.find 方法被执行,但我怀疑你的 Track.find 方法的返回总是未定义的,如果不是未定义的,你将它应用于不会在承诺中返回的东西,所以你正在做的操作不会反映在你的承诺中,就像创建一个变量而不使用它。 【参考方案1】:

我认为 promise 没有被执行,而且我认为您在 getDate 函数中指向一个未定义的对象,并且 for 循环不会等待 promise 被解决或拒绝。看到这个:

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);

那么你应该使用 async - await 来强制循环在 promise 处暂停,直到它被解决或拒绝,所以你的匿名函数现在应该是一个异步匿名函数,以便使用 await,你也不要'不需要在另一个承诺中包装一个承诺,我的意思是你不需要这个:

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

你只需要这个:

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

因为 getDate() 函数本身返回一个承诺。

这就是你的代码在进行所有这些更改后的样子:

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);
      );

现在您将响应作为一个承诺,因为 async 函数返回一个承诺...然后您可以捕获它并使用响应:

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

【讨论】:

以上是关于在 for 循环中使用 Promise的主要内容,如果未能解决你的问题,请参考以下文章

如何在Django模板的内部for循环中使用外部for循环值

js中for循环和while循环在使用的时候有何区别?

为啥 for..of / for..in 循环可以使用 const 而普通的 for 循环在 JS 中只能使用 let 或 var 作为其变量? [复制]

在 for 循环中使用 Promise

js中for循环和while循环在使用的时候有何区别?

java中使用增强型的for循环有啥好处?