背景

有一个从后端获取的数据列表,每页请求10条,每次下拉到底部的是时候请求下一页。目前做法是,请求下一页的时候底部显示loading,有个问题就是如果接口返回比较慢,loading则会显示的比较久

什么是事件循环

假如你是一个餐馆老板,你有一个主要工作台(主线程)和两个不同的便签板,一个贴在工作台旁(微任务板),另一个挂在门边(宏任务板)。

同步任务:任何走进餐馆直接点菜的顾客,你立即处理他们的订单,相当于同步任务,直接在主线程上执行。

微任务(快速便签板) :现在,假设顾客吃饭过程中,要求加一杯水。你告诉他们“稍等,我马上来”,然后迅速在微任务板上写下“送水”(微任务),然后继续处理当前排队的客户。处理完排队的客户转身就能看到并立刻执行快速便签板上的微任务。

宏任务(门边便签板) :而对于预约外卖的顾客,你记录下来,贴在门边的宏任务板上,这些任务相对不那么紧急,你打算在完成当前所有桌面上的服务后,以及处理完微任务板上的所有小事后,再去查看并逐一完成。比如,制作外卖、清理餐桌等,这些任务耗时较长,不会立刻执行,但也不会忘记做。

事件循环怎么和数据预加载关联起来

当我们请求好第一页数据后,将请求下一页放到异步任务队列里(宏任务或者微任务),等当前同步任务执行完成后,立马请求下一页数据

实现

请求数据

// 从服务器请求数据
loadData(page) {
  // '''''
  return list
}

请求下一页,异步任务

  • 小程序实现
//-------------------------页面初始化的时候---------------------------------------
this.setData({
    list: await loadData(page)
})
// wx.nextTick创建异步任务,等待空闲后执行
wx.nextTick(async () => {
   // 下一页数据先放在变量里面存起,等滑动到底部的时候将nextList追加到list,并且预请求再下一页
   const nextList = await loadData(page + 1)
})
//-------------------------页面下滑到底部的时候---------------------------------------
this.setData({
    list: [...this.data.list, ...nextList]
})
// wx.nextTick创建异步任务,等待空闲后执行
wx.nextTick(async () => {
   // 下一页数据先放在变量里面存起,等滑动到底部的时候将nextList追加到list,并且预请求再下一页
   const nextList = await loadData(page + 1)
})
  • 非小程序实现
// 创建一个异步任务
 MicroTasks(callback: () => {}) {
    Promise.resolve().then(() => {
        callback()
    })
 }
 
 // 将上述wx.nextTick换成MicroTasks,其他不变
  MicroTasks(async () => {
     const nexList = await loadData(page + 1)
 })

扩展

由上面的事件循环例子可以知道,异步任务是需要等同步任务全部执行完成了才会被执行,那如果到异步任务应该执行的时间点了,同步任务还没有执行完,那异步任务就会被推迟

举个例子,我们写了一个setInterval(() => {}, 1000),1000毫秒后setInterval回调任务会被放入异步任务队列,如果同步任务还没执行完成,这个异步任务会被推迟,如果,又过了1000毫秒,下一个异步任务都被放进异步队列了,上一个还没被执行,就会造成任务积压。可以通过 setTimeout自调用解决积压,但是解决不了高负载情况下的延迟

  • setTimeout自调用例子
let timeoutId;

function customInterval(callback, delay) {
    function execute() {
        // 执行你的任务...
        callback();
        
        // 根据任务执行情况决定是否继续调用
        if (/* 需要继续执行的条件 */) {
            timeoutId = setTimeout(execute, delay);
        }
    }
    
    // 立即开始第一次执行
    execute();
}

// 使用示例
customInterval(() => {
    console.log('执行中...');
    // ...你的任务代码
}, 1000); // 延迟1000毫秒

// 如果需要停止循环,可以通过 clearTimeout(timeoutId); 来实现

到此这篇关于JavaScript利用事件循环实现数据预加载的文章就介绍到这了,更多相关JavaScript数据预加载内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部