为了账号安全,请及时绑定邮箱和手机立即绑定

使用可观察量为顺序动画制作可取消的 setTimeouts

使用可观察量为顺序动画制作可取消的 setTimeouts

慕丝7291255 2023-07-29 15:03:06
我有一个对象数组,根据对象的类型键代表不同的动画。我使用setTimeout. 我正在反应组件的函数内运行下面的代码。animations.forEach((animation, index) => {      switch (animation.type) {        case "animation-type": {          setTimeout(() => {            //change the style of some elements          }, index * 1000);          break;        }        ...        default:          break;      }});上面的整个过程按预期正常运行,只是一旦开始我就无法停止。我希望能够出于某种原因在某个时刻停止该过程,并取消等待轮到的剩余动画。我正在寻找一种简单的方法来以声明方式执行此操作,我能想到的唯一选择是使用 rxjs 中的可观察量来使该过程可取消。然而,我很难调整上面的过程来使用可观察量,因为我对 rxjs 还很陌生。长话短说,我想让这个过程可以取消。
查看完整描述

2 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

下面的流zip创建每 1000 毫秒向订阅的 lambda 发送一个对象。一旦不再有任何对象,它就会结束。


takeUntil是可用于控制流何时结束的更通用的运算符之一。在这种情况下,当cancel$发出一个值时,整个流就结束了。


const cancel$ = new Subject();

zip(

  from(animations), 

  interval(1000)

).pipe(

  takeUntil(cancel$),

  map(([x,y]) => x)

).subscribe(animation => {

  switch (animation.type) {

    case "animation-type": {

      //change the style of some elements

      ...

    default:

      break;

  }

});

然后,如果您需要停止它,您可以运行此行


cancel$.next();

当然,您可以传入一个观察者对象,而不是使用 lambda 函数进行订阅。


).subscribe({

  next: animation => {

    switch (animation.type) {

      case "animation-type": {

        //change the style of some elements

        ...

      default:

        break;

    }

  },

  complete: () => {

    // Final touches/ reset the animation/ whatever

  },

  error: err => {

    console.log("Got an error: " + err.message);

    throw(err);

  }

})


查看完整回答
反对 回复 2023-07-29
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

您可以存储超时函数:



    const timeouts = [];


    animations.forEach((animation, index) => {

          switch (animation.type) {

    

            case "animation-type": {

    

              timeouts[index] = setTimeout(() => {

                //change the style of some elements

              }, index * 1000);

    

              break;

            }

    

            ...

    

            default:

              break;

          }

    });


然后:


timeouts.map(timer=> clearTimeout(timer));

如果您正在使用 React 项目,则可以使用useRef钩子


    const timeouts = useRef([]);



    animations.forEach((animation, index) => {

          switch (animation.type) {

    

            case "animation-type": {

    

              timeouts.current[index] = setTimeout(() => {

                //change the style of some elements

              }, index * 1000);

    

              break;

            }

    

            ...

    

            default:

              break;

          }

    });

并清除超时:


timeouts.current.map(timer=> clearTimeout(timer));


查看完整回答
反对 回复 2023-07-29
  • 2 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信