setTimeout()如何返回值

5
我想返回状态并将其值存储在变量s中。请帮忙一下,谢谢。
这是我的代码:
let s = setTimeout( ()=>{
   this.matchService.getMatches().subscribe(ms => {
       this.matches = ms;
       let match = this.matches.find(match => match.id == id);
       let status = match.status;
       if(status == 'closed' || status == 'live') {
          this.status.name = status;
        }
        return status;
      });
  },9000);
}

4
setTimeout()函数确实会返回一个值,这个值是计时器本身的标识符。但是你不能从回调函数中返回任何东西,这没有意义。 - Pointy
s会发生什么?运行后里面是什么? - srknzl
@user11290658 既然你正在使用Angular,就把它存储在组件中吧。不过这个东西的作用是什么呢?能否提供更多代码一起处理呢?以我看来,你可能走错了方向。 - briosheje
@user11290658 不行。调用setTimeout()会立即返回;周围的代码不会等待计时器。 - Pointy
@user11290658 如果值在9秒后发生变化会怎么样?这就是我想知道的。在这里使用间隔似乎更加合适。 - briosheje
显示剩余4条评论
2个回答

8
这个回答是针对setTimeout问题的。如果你使用可观察对象,请考虑bambam的答案!
好的,如果你不了解异步的概念,这个答案可能有点奇怪。 基本上最简单的方法是将你的setTimeout包装成一个Promise,像这样:

const someTimeoutAction = () => {
  // Let's return a new Promise, promising to eventually return a value
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello world');
    }, 1000);
  });
};

// The following function is an async function, that will
// help to work better with Promises.
const mainFunction = async () => {
  console.log('Waiting for status');
  const status = await someTimeoutAction();
  console.log(status);
};
mainFunction();

这里发生了什么?

  1. mainFunction被调用并调用someTimeoutAction
  2. someTimeoutAction返回一个Promise。旧的语法看起来有些不同。这篇中等文章应该是一个很好的起点。
  3. mainFunction等待Promise解析。一秒钟后,它被解析并将该值写入status
  4. 现在其他所有内容都像往常一样继续执行。

上面的代码仅适用于现代浏览器。对于例如IE11等浏览器,它不会自动工作,需要使用转换器进行转换。 不过,旧的语法仍然可以正常工作:

function someTimeoutAction() {
  // Let's return a new Promise, promising to eventually return a value
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello world');
    }, 1000);
  });
};

// The following function is an async function, that will
// help to work better with Promises.
function mainFunction() {
  console.log('Waiting for status');
  someTimeoutAction()
    .then(function(status) {
      console.log(status);
    });
};
mainFunction();


请注意,旧版浏览器需要使用转译器 - Ruan Mendes
1
好的。我已经使用旧语法更新了我的答案。 - lumio
谢谢,这对我很有效。 - Isuru Maldeniya

5

由于你已经有了一个可观察对象,所以只需延迟它即可,而不是使用setTimeout!此外,其他答案中的承诺方法对于这种情况是无意义的。

this.matchService.getMatches()
    .pipe(delay(9000))
    .subscribe(ms => {
       this.matches = ms;
       let match = this.matches.find(match => match.id == id);
       let status = match.status;
       if(status == 'closed' || status == 'live') {
          this.status.name = status;
       }
  });

你的代码存在一个更大的问题,就是你永远不会从订阅中返回。实际上,你应该延迟(我猜测是)matchService中的http调用,但是你没有展示相关的代码。
请注意,订阅可能会多次触发,这取决于getMatches()是什么意思。你现在走错了方向,应该更新你的问题,以便我们可以为你量身定制一个真正的解决方案。

你可以直接返回一个 Promise 并与 async 结合使用:return this.matchService.getMatches().pipe(delay(9000)).toPromise().then((v)=>v.something) - Ruan Mendes
不需要 @JuanMendes,真的完全不需要。 - baao
1
@JuanMendes 这是Angular,为什么需要一个Promise?在这种情况下,使用Promise的超时方法,在像Angular这样的框架中,对我来说概念上是错误的。我不是说它不起作用,只是很奇怪。 - briosheje
2
@JuanMendes 这个问题是关于在数据库值改变时更新标志位,它听起来不像是 Promise 任务。再次强调,我并不是说这样做是错的,只是说这个设计很奇怪。添加一个 Promise 并不能解决问题,只会增加更多不必要的代码,因为结果可以直接绑定到 Angular 属性上,而不需要 Promise 或其他东西。只是 OP 选择的设计是错误的,因为检查值是否改变的任务不能使用超时完成,并且在 Angular 中,这应该不是组件的任务。 - briosheje
1
@user11290658,按照设计(注意,我在谈论“设计”),组件不应该永久调用服务。相反,服务应该在值改变时通知组件,组件应该在这种情况下采取行动。在这种情况下,服务应该有一个间隔,并且实际上应该调用服务器,并且应该在满足条件时发出值。如果是这种情况,请更新您的示例,以便我们可以正确地帮助您。 - briosheje
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接