首页 > 解决方案 > setTimeout 在 for 循环内发送通知

问题描述

我正在尝试根据某些参数发送通知,并且尝试使用 for 循环和 setTimeout,但是当我运行它时,所有通知都会立即发送。代码如下所示:

this.times 是一个 n 维数组。this.timer 是基于用户输入的变量

for(let i of this.times) {
      this.localNotification()
    }
localNotification() {
    setTimeout(() => {
      this.date = new Date()
      this.localNotifications.schedule({
      text: "Hey it's time to take a picture",
      trigger: {at: new Date(new Date().getTime())},
      led: 'FF0000',
      sound: 'file:/storage/emulated/0/media/audio/notifications/CwtChime.ogg'
      })
      this.notificationList.unshift({Title: "Time to take a picture", Body: "Hey, it's been a week since you took a picture, please take one", Reminder: true, Time: `${this.date.toLocaleString()}`, Seen: false})
    }, this.timer*1000)
  }

当我尝试运行它时,所有通知都会立即发送,并且我很难理解如何以不同的方式进行操作。

标签: angulartypescriptionic-framework

解决方案


欢迎来到 SO!这是因为 setTimeout 函数是非阻塞的,并且会立即返回,因此循环将非常快速地设置所有计时器,并且所有计时器几乎同时触发,因此您看不到差异。如果您想延迟发送通知,您可以在循环中添加一些延迟,如下所示:

const timer = ms => new Promise(res => setTimeout(res, ms))

async function sendAllNotifications () { // We need to wrap the loop into an async function for this to work
  for (let i of this.times) {
    this.localNotification()
    await timer(this.timer*1000); // then the created Promise can be awaited
  }
}

sendAllNotifications();

您的 localNotification 函数将变为:

localNotification() {      
      this.date = new Date()
      this.localNotifications.schedule({
      text: "Hey it's time to take a picture",
      trigger: {at: new Date(new Date().getTime())},
      led: 'FF0000',
      sound: 'file:/storage/emulated/0/media/audio/notifications/CwtChime.ogg'
      })
      this.notificationList.unshift({Title: "Time to take a picture", Body: "Hey, it's been a week since you took a picture, please take one", Reminder: true, Time: `${this.date.toLocaleString()}`, Seen: false})
  }

推荐阅读