首页 > 编程语言 >短视频app源码,借助轮询优化交互体验

短视频app源码,借助轮询优化交互体验

时间:2024-09-07 08:51:36浏览次数:6  
标签:异步 请求 app await timer 源码 轮询 加载

业务背景

在短视频app源码前后端数据交互场景下,使用最多的一种方式是客户端发起 HTTP 请求,等待服务端处理完成后响应给客户端结果。
但在一些场景下,短视频app源码服务端对数据的处理需要较长的时间,比如提交一批数据,对这批数据进行数据分析,将最终分析结果返回给前端。
如果采用一次 HTTP 请求,用户会一直处于等待状态,再加上界面不会有进度交互,导致用户不知何时会处理完成;此外,一旦刷新页面或者其他意外情况,用户就无从感知处理结果。
面对这类场景,可以借助 「HTTP 轮询方式」 对交互体验进行优化,具体过程如下:
首先发起一次 HTTP 请求用于提交数据,之后启动轮询在一定间隔时间内查询分析结果,在这期间后台可将分析进度同步到前端来告知用户处理进度;此外即使刷新再次进入页面还可以通过「轮询」实时查询进度结果。
下面,我们来看看代码层面看如何实现这类场景。

JS 实现轮询的方式

在实现代码之前,我们需要先明确 JS 实现轮询的方式有哪些,哪种方式最适合使用。

1. setInterval

作为前端开发人员,提起轮询第一时间能想到的是计时器 setInterval,它会按照指定的时间间隔不间断的轮询执行处理函数。

let index = 1;

setInterval(() => {
  console.log('轮询执行: ', index ++);
}, 1000);

 

回过头来看我们的场景:要轮询的是 异步请求(HTTP),请求响应结果会受限制网络或者短视频app源码的服务器处理速度,显然 setInterval 这种固定间隔轮询并不适合这个场景。

2. Promise + setTimeout sleep

setInterval 的不足之处在于 轮询间隔时间 在异步请求场景下无法保证两个请求之间的间隔固定。要解决这个问题,可以使用 sleep 睡眠函数来控制间隔时间。
JS 中没有提供 sleep 相关方法,但可以结合 Promise + setTimeout 来实现。

const sleep = () => {
  return new Promise(resolve => {
    setTimeout(resolve, 1000);
  });
}

 

sleep 仅控制了轮询间隔,而轮询的执行机制需要我们手动根据异步请求结果来实现,比如下面通过控制 while 循环的条件:

const start = async () => {
  let i = 0;
  while (i < 5) {
    await sleep();
    console.log(`第 ${++ i} 次执行`);
  }
}

start();

 

使用轮询的时候可以借助 async/await 同步的方式编写,提高代码阅读质量。

实现异步请求轮询

下面我们通过一个完整示例理解 轮询异步请求 的实现及使用注意事项。
首先我们定义两个变量:index 用于控制何时停止轮询,timer 则用于实现中断轮询。

let index = 1;
let timer = 0;

 

这里,我们定义 syncPromise 来模拟异步请求,可以看作是一次 HTTP 请求,当进行 5 次异步请求后,会返回 false 表示拿到数据分析结果,停止数据查询轮询:

const syncPromise = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`第 ${index} 次请求`);
      resolve(index < 5 ? true : false);
      index ++;
    }, 50);
  })
}

 

现在,我们实现 pollingPromise 作为 sleep 睡眠函数使用,去控制轮询的间隔时间,并在指定时间执行异步请求:

const pollingPromise = () => {
  return new Promise(resolve => {
    timer = setTimeout(async () => {
      const result = await syncPromise();
      resolve(result);
    }, 1000);
  });
}

 

最后,startPolling 作为开始轮询的入口,包含以下逻辑:

1)在轮询前会清除正在进行的轮询任务,避免出现多次轮询;
2)如果需要,在开始轮询时会立刻调用异步请求查询一次数据结果;
3)最后,通过 while 循环根据异步请求的结果,决定是否继续轮询;

const startPolling = async () => {
  // 清除进行中的轮询,重新开启计时轮询
  clearTimeout(timer); // !!! 注意:清除计时器后,会导致整个 async/await 链路中断,若计时器的位置下方还存在代码,将不会执行。
  index = 1;
  // 立刻执行一次异步请求
  let needPolling = await syncPromise();
  // 根据异步请求结果,判断是否需要开启计时轮询
  while (needPolling) {
    needPolling = await pollingPromise();
  }
  console.log('轮询请求处理完成!'); // 若异步请求被 clearTimeout(timer),这里不会被执行打印输出。
}

const start = async () => {
  await startPolling();
  console.log('若异步请求被 clearTimeout(timer),这里将不会被执行');
}
start();

 

不过,需要注意的是:一旦清除计时器后,会导致整个 async/await 链路中断,若计时器的位置下方还存在代码,将不会执行。
假设当前执行了两次轮询被 clearTimeout(timer) 后,从 startPolling 到 start 整个 async/await 链路都会中断,且后面未执行的代码也不会被执行。
基于以上规则,异步轮询的处理逻辑尽量放在 syncPromise 异步请求核心函数中完成,避免在开启轮询的辅助函数中去实现。

使用轮询的其他场景

在短视频app源码中,使用轮询的场景还有很多。
通常我们考虑首屏加载速度,会将一些非主要启动程序的资源改用 动态异步 的方式去加载。
如果某个页面渲染时依赖了异步加载的脚本资源,就会出现无法拿到资源变量导致报错情况,因为这个时候其实资源还没有加载完成。
所以就需要一种手段,在资源加载完成后再让页面拿去使用,轮询脚本资源变量是否存在可以作为一种处理方式。

/**
 * 轮询查询异步资源的加载状态
 */
export const pollingAsyncResource = (handler: Function, condition: () => unknown) => {
  let timer = 0;
  if (!!condition()) {
    // 静态资源已加载完成
    handler();
  } else {
    // 启动轮询查询静态资源加载状态
    timer = window.setInterval(() => {
      if (condition()) {
        // 静态资源已加载完成
        clearInterval(timer);
        handler();
      }
    }, 50);
  }
}

// 使用
pollingAsyncResource(
  () => // 使用资源的具体逻辑, 
  () => window.$
);

 

在 pollingAsyncResource 中启动 计时器轮询 去查询静态资源是否加载完成。
参数 handler 是资源加载完成后要执行的具体逻辑;condition 则是判断资源是否加载完成的条件,一般脚本资源都采用 umd 模块形式在 window 对象上绑定全局变量。

以上就是短视频app源码,借助轮询优化交互体验, 更多内容欢迎关注之后的文章

 

标签:异步,请求,app,await,timer,源码,轮询,加载
From: https://www.cnblogs.com/yunbaomengnan/p/18401314

相关文章

  • 25届毕设选题推荐-图书管理系统用小程序开发,如何实现快速借阅?uniapp 帮你高效搞定!
    博主介绍:✌十余年IT大项目实战经验、在某机构培训学员上千名、专注于本行业领域✌技术范围:Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫+大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战项目。主要内容:系统功能设计、开题报告......
  • 计算机毕业设计选题推荐-用小程序和UniApp开发志愿者管理系统,快速提升公益活动参与度!
    博主介绍:✌十余年IT大项目实战经验、在某机构培训学员上千名、专注于本行业领域✌技术范围:Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫+大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战项目。主要内容:系统功能设计、开题报告......
  • Dubbo源码剖析-SPI机制(超详细深度剖析篇)
    目录什么是SPISPI的工作原理SPI的作用SPI的缺点简单使用JDK的SPI与Dubbo的SPIDubbo为什么要使用SPI机制DubboSPI源码分析小结什么是SPI        SPI全称为ServiceProviderInterface,一种解耦接口和实现的手段,其实现原理是将接口的实现类全名称配置......
  • Java毕业设计-基于SSM框架的高校外事管理系统项目实战(附源码+论文)
    大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。......
  • Java毕业设计-基于SSM框架的图书借阅管理系统项目实战(附源码+论文)
    大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。......
  • Spring 源码解读:实现Spring容器的启动流程
    引言Spring容器的启动流程是Spring框架中最为基础且重要的部分。通过对Spring容器的启动机制进行解读,我们可以更加清晰地理解Spring是如何管理Bean的生命周期、如何处理依赖注入等核心功能。本篇文章将通过手动实现一个简化的Spring容器启动流程,并与Spring实际的启动过程......
  • jsp仓储管理系统9e8ai 本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上
    jsp仓储管理系统9e8ai本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能客户,库存人员,入库人员,出库人员,商品类别,商品信息,仓区信息,商品入库,商品出库开题报告内容一、项目背景与意义随着电子商......
  • Uniapp核心基础(一)
    特点uni-app是一个使用Vue.js开发所有前端应用的框架,它允许开发者编写一套代码,然后发布到iOS、Android、Web(响应式)、以及各种小程序(如微信、支付宝、百度、头条等)等多个平台。以下是对uni-app核心基础的详细解析:一、核心特性跨平台开发:uni-app的最大特点是跨平台,一套代码可......
  • vue.js项目实战案例源码
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • 汉服女装商城购物主题html网页成品 | html学生网页源码
    文章目录网站主题网站描述网站介绍网站演示学习理念更多干货一、网站主题女装商城网站、女装购物网站、服装商城网站、购物商城网站、电商主题网站、网页设计与制作二、网站描述网页简介:此作品为学生网页设计毕设服装商城购物网页设计题材(汉服,是汉民族的传统服饰。又称......