Javascript 如何使用setInterval()返回承诺
我试图以1000ms的速度返回一个Promise对象,但我不确定在Promise中返回的数据在Javascript 如何使用setInterval()返回承诺,javascript,promise,setinterval,Javascript,Promise,Setinterval,我试图以1000ms的速度返回一个Promise对象,但我不确定在Promise中返回的数据在setInterval()回调中时如何访问它 编辑 我似乎不太清楚我的意图,所以我将尝试解释我正在尝试做什么。I进行倒计时,根据规定的结束日期,每1000毫秒进行一次必要的计算 下面是提供返回值的代码,我希望每1000ms返回一个Pormise值: calculateTimeRemaining(endDate: string) { const { secondsInDay, da
setInterval()回调中时如何访问它
编辑
我似乎不太清楚我的意图,所以我将尝试解释我正在尝试做什么。I进行倒计时,根据规定的结束日期,每1000毫秒进行一次必要的计算
下面是提供返回值的代码,我希望每1000ms返回一个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;
}
示例:
const interval = window.setInterval(() => {
return new Promise((resolve, reject) => {
resolve('Hello');
});
}, 1000);
interval.then((data) => console.log(data);
之后如何使用.then()
访问Promise对象
不起作用:
const interval = window.setInterval(() => {
return new Promise((resolve, reject) => {
resolve('Hello');
});
}, 1000);
interval.then((data) => console.log(data);
setInterval
已返回一个整数,该整数可用于使用clearInterval
取消此间隔
const promise = new Promise((resolve, reject) => {
resolve('Hello');
});
然后像这样使用它
promise.then((result) => {
console.log(result) // Says 'Hello' and will not resolve another value if we call it as it has already been resolved
})
也许这就是你想要达到的。
如果你想以1000毫秒的间隔调用它
const getPromiseInstance = () => new Promise((resolve, reject) => {
resolve(Math.random());
});
setInterval(() => {
getPromiseInstance().then((result) => {
console.log(result)
})
}, 1000)
您应该看看Observable,它可能会满足您的需要这取决于您实际要做的事情,异步iterable可能会完成这项工作
不同之处在于,只有在使用最后一个承诺时,异步iterable才会生成下一个承诺。JavaScript中的间隔很棘手,即使没有承诺。他们尝试定期运行回调,但是如果解释器忙,任何回调的执行都可能会延迟。不过,这种延迟不会传播。此外,对于背景选项卡,短时间间隔也将被限制
假设您的代码总是等待使用异步iterable(例如,在for…of
循环中),您可以执行以下操作:
function delay(t) {
return new Promise(resolve => setTimeout(resolve, t))
}
async function *interval(t) {
while(true) {
let now = Date.now()
yield "hello"
await delay(now - Date.now() + t)
}
}
for await(const greeting of interval(1000)) console.log(greeting)
正如评论中已经提到的,您不能在时间间隔内返回承诺,但可以将其保存在全局对象中,稍后使用
const jobs=[]
常量间隔=设置间隔(()=>{
如果(jobs.length==10){
间隔时间;
}
let job=Promise.resolve(‘新创建的作业’);
推(作业);
console.log('已创建作业')
}, 1000);
设置超时(()=>{
Promise.all(作业).then(数据=>console.log(数据))
}, 1000*15);代码>您所寻找的是可观察的,而不是承诺。有了承诺,您传递给的回调最多执行一次,因此:
interval.then((data) => console.log(data));
…将不会多次打印“Hello”,即使您更正了代码中的以下错误:
- 在
setInterval
回调函数中返回的任何内容都将被忽略
setInterval
不返回承诺,而是一个整数,唯一标识创建的间隔计时器
另一方面,与承诺相反,可观察对象可以发出多个事件
EcmaScript有一个版本,但您可以创建自己的非常简化的版本:
可观察的类{
构造函数(exec){
this.listeners=新集合;
执行官({
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()
});
}
订阅(侦听器){
this.listeners.add(listeners);
返回{unsubscribe:()=>this.listeners.delete(listeners)}
}
}
//创造一个可观察的而不是承诺;
常数间隔=新的可观测({next})=>{
setInterval(()=>next(“Hello”),1000;
});
//同意这一观点
const subscription=interval.subscripte({next:(数据)=>console.log(数据)});
//(可选)使用返回的订阅对象停止侦听:
document.querySelector(“按钮”).addEventListener(“单击”,订阅。取消订阅)代码>
停止侦听
对于间隔,您可以这样定义间隔函数
function interval() {
return new Promise(function(resolve, reject) {
setInterval(function() {
resolve('Hello');
}, 1000)
})
};
对于间隔,您可以使用以下选项:
方式1:
interval().then((x) => {
console.log(x);
})
方式2:
const intervalId = setInterval(() => {
interval().then((x) => {
console.log(x);
},1000)
})
这只是为了在一段时间后停止间隔函数。
如果不再需要间隔,则必须清除间隔
setTimeout(() => {
clearInterval(intervalId);
}, 10000);
我不确定这是否有帮助,但是;任何函数都可以做成承诺,在这种情况下,可选语法[async关键字]可能对您有用
async function test() {
return "hello";
}
test().then( returned => console.log(returned)) // logs hello
但是,setInterval()不返回返回值,而是返回“句柄”
句柄=窗口。setInterval(处理程序[,超时[,参数]])
。。。
然而,你可以在设定的时间间隔内做出承诺
interval = window.setInterval(makepromise,1000)
async function makepromise() {
console.log("hello");
}
//或
但那时候没有地方休息。我们又回到了我们试图避免的回调!但是,在这个函数中,我们可能可以使用wait
最好是让你的计算符合一个承诺,然后你就可以在区间使用then
interval = window.setInterval(gameloop,1000);
function gameloop(endDate: string) {
calculateTimeRemaining(endDate: string).then(
//
// my then code goes here.
//
)
}
async 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;
}
然而,承诺的价值在于避免使用过于复杂的回调方案带来回调地狱。。。其中代码是回调、回调、回调等等
承诺不会像webworker那样在第二个操作系统线程中运行。因此,除非您试图清理回调以使代码可读,或者实际上正在等待某些东西,否则使用承诺没有任何好处
setInterval是一个干净的回调。Gameloop示例并不容易阅读和理解,因为使用了承诺。我建议在这种情况下,它更难阅读。在这一点上。。。除非循环中还有其他等待或一系列不需要同步运行的承诺 承诺只解决一次,因此您想要实现的并不明确我认为您正在寻找的是一个异步Iterabley您不应该返回并在setInterval内运行您的承诺setInterval
返回间隔引用,它不返回回调的返回。此外,承诺只能解决一次。你想完成什么?你只能返回一次,不能