如何使用 setInterval() 返回 Promise

Fre*_*ers 0 javascript setinterval promise

我试图每 1000 毫秒返回一个 Promise 对象,但我不确定如何访问 Promise 在setInterval()回调中返回的数据。

编辑 我似乎不太清楚我的意图,所以我会尝试解释我想要做什么。我倒计时,根据指定的结束日期,每 1000 毫秒进行一次必要的计算。

这是提供我希望每 1000 毫秒作为 Pormise 值返回的返回值的代码:

calculateTimeRemaining(endDate: string) {
            const { secondsInDay, daysOfYear, secondsInHour, secondsInMinute } = this.unitsOfTime;
            let distance: number =
                (Date.parse(new Date(endDate).toString()) - Date.parse(new Date().toString())) / this.increment;

            if (distance > 0) {
                // Years left
                if (distance >= daysOfYear * secondsInDay) {
                    // 365.25 * 24 * 60 * 60
                    this.timeRemaining.years = Math.floor(distance / (daysOfYear * secondsInDay));
                    distance -= this.timeRemaining.years * daysOfYear * secondsInDay;
                }
                // Days left
                if (distance >= secondsInDay) {
                    // 24 * 60 * 60
                    this.timeRemaining.days = Math.floor(distance / secondsInDay);
                    distance -= this.timeRemaining.days * secondsInDay;
                }
                // Hours left
                if (distance >= secondsInHour) {
                    // 60 * 60
                    this.timeRemaining.hours = Math.floor(distance / secondsInHour);
                    distance -= this.timeRemaining.hours * secondsInHour;
                }
                // Minutes left
                if (distance >= secondsInMinute) {
                    // 60
                    this.timeRemaining.minutes = Math.floor(distance / secondsInMinute);
                    distance -= this.timeRemaining.minutes * secondsInMinute;
                }
                // Seconds left
                this.timeRemaining.seconds = distance;
            }
            return this.timeRemaining;
        }
Run Code Online (Sandbox Code Playgroud)

例子:

    const interval = window.setInterval(() => {
        return new Promise((resolve, reject) => {
            resolve('Hello');
        });
    }, 1000);
Run Code Online (Sandbox Code Playgroud)

之后如何访问 Promise 对象.then()

不起作用:

interval.then((data) => console.log(data);
Run Code Online (Sandbox Code Playgroud)

tri*_*cot 6

你正在寻找的是一个 Observable,而不是一个 Promise。使用承诺,您传递给的回调then最多执行一次,因此:

interval.then((data) => console.log(data));
Run Code Online (Sandbox Code Playgroud)

...永远不会多次打印“Hello”,即使您更正了代码中的以下错误:

  • 无论你returnsetInterval回调函数被忽略。
  • setInterval 不返回承诺,而是一个整数,唯一标识创建的间隔计时器。

另一方面,与 Promise 相反,Observable可以发出多个事件。

EcmaScript有一个Observable 提议,但您可以创建自己的——非常简化的——版本:

interval.then((data) => console.log(data));
Run Code Online (Sandbox Code Playgroud)
class Observable {
    constructor(exec) {
        this.listeners = new Set;
        exec({
            next: (value) => this.listeners.forEach(({next}) => next && next(value)),
            error: (err) => this.listeners.forEach(({error}) => error && error(err)),
            complete: () => this.listeners.forEach(({complete}) => complete && complete())
        });
    }
    subscribe(listeners) {
        this.listeners.add(listeners);
        return { unsubscribe: () => this.listeners.delete(listeners) }
    }
}

// Create an Observable instead of a Promise;
const interval = new Observable(({next}) => {
    setInterval(() => next("Hello"), 1000);
});

// Subscribe to that Observable
const subscription = interval.subscribe({ next: (data) => console.log(data) });

// Optionally use the returned subscription object to stop listening:
document.querySelector("button").addEventListener("click", subscription.unsubscribe);
Run Code Online (Sandbox Code Playgroud)

请注意,一些 JavaScript 框架具有Observable.


Dis*_*ure -3

setInterval已经返回一个整数,这对于取消此间隔很有用,使用clearInterval.

const promise = new Promise((resolve, reject) => {
        resolve('Hello');
    });

Run Code Online (Sandbox Code Playgroud)

然后像这样使用它


promise.then((result) => {
 console.log(result) // Says 'Hello' and will not resolve another value if we call it as it has already been resolved
})
Run Code Online (Sandbox Code Playgroud)

也许这就是你试图实现的目标。如果你想以1000毫秒的间隔调用它。

const getPromiseInstance = () => new Promise((resolve, reject) => {
        resolve(Math.random());
    });

setInterval(() => {
    getPromiseInstance().then((result) => {
      console.log(result)
    })
}, 1000)
Run Code Online (Sandbox Code Playgroud)

你应该看看 Observable,也许它会满足你的需求