vlambda博客
学习文章列表

Ajax 异步与同步(jQuery 在函数中修改全局变量)

    还是最近在做的那个漫画网站,商定详情页面以无限下拉方式来体现,取消古板的下一章,下一页这样的高频点击按钮。这种方式的请求就得用Ajax来发送。首先绑定一个下拉滚动条到达某一位置的事件函数,然后在其中编写Ajax的逻辑。这里呢首先就遇到一个问题:由谁来决定请求的内容?这个问题在我当前的具体业务中前端后端都可以实现,无非就是谁来做,谁的逻辑就会复杂一点,考虑到前端朋友天天带刀上班,于是主动把这个任务交予后端来做……手动狗头保命

    具体方式就是在后端响应的数据中,除了发送当前请求的图片URL之外,还要包含前端下一次请求的具体内容(哪本漫画,哪一章节,哪一页),这样前端就只需要把响应数据存下来,等着下一次发送请求就OK了。

    如何存储响应数据呢?这里可以使用jQuery调用cookie来保存数据,但是小玉觉得呢,cookie这个东西,貌似不是每种客户端都有的,于是想了一个偏方……创建全局变量来存储这三个数据。

Ajax 异步与同步(jQuery 在函数中修改全局变量)

由于Ajax是在函数内部执行,无法直接对全局变量进行修改,需要用到一个方法:window.变量名 = 数据;    这样就可以修改函数体外部的全局变量。

Ajax 异步与同步(jQuery 在函数中修改全局变量)

    小玉一开始设计的是,当滚动条触底之后,向后端发起三次请求,每一次请求的参数,都由上一次请求的响应来决定。设计是很美好的,直到运行程序……

Ajax 异步与同步(jQuery 在函数中修改全局变量)

这里小玉完全忽略了Ajax最根本的属性:异步性,导致了什么样的结果呢:

上图里的两条控制台打印语句,想要的是一对一的交替打印,结果却是:

Ajax 异步与同步(jQuery 在函数中修改全局变量)

这样的结果意味着,同样的请求,发了两次(实际上看网页页面效果是同样的请求发了三次)(别问,我也不明白)

这就是Ajax异步的效果体现,那个for语句不会等到Ajax执行完毕再开始下一轮循环,它会直接将三次循环全部执行,就像是后端的线程池技术。

要解决这个问题,百度给出的方案是:将Ajax从异步变为同步,这个方案一开始小玉是不同意的,Ajax本来就是一个前端的异步技术,这下要把它设置成同步来运行,这TM不是疯了吗???奈何自己也没有找到更好的办法来解决这个问题,于是,疯了就疯了吧……最终还是给Ajax添加了一行属性:


Ajax 异步与同步(jQuery 在函数中修改全局变量)

这条属性就是让Ajax采用同步运行的方式。

Ajax 异步与同步(jQuery 在函数中修改全局变量)

虽然输出变成了想要的样子,但是浏览器也给出了一条赤裸裸的提示:不建议使用同步的方式!

后来小玉仔细想了想,感觉还有一种办法貌似能够在不设置同步的情况下实现这一需求:那就是去掉for循环,直接把Ajax嵌套三层Ajax 异步与同步(jQuery 在函数中修改全局变量)

我擦,你别说蠢,这种办法还真的行

Ajax 异步与同步(jQuery 在函数中修改全局变量)

于是,小玉决定采用这种看起来很蠢的办法,至少不会弹警告Ajax 异步与同步(jQuery 在函数中修改全局变量)

最后,素质三连,赠送代码

<div id="container" style="text-align: center"></div><div class="scrollerFooter1"> 没有内容了</div>
<script> var bookID = {{ book_id }}; var chapterID = {{ chapter_id }}; var page = 1;
function infinityScroll(footerNode, callback) { var observer = new IntersectionObserver(function (changes) { if (changes[0].intersectionRatio <= 0) return; callback(); }); observer.observe(document.querySelector(footerNode)); } infinityScroll('.scrollerFooter1', function pictuer(i=3) { $.ajax({ url: '/index/content/' + bookID + '/' + chapterID + '/' + page, type: 'GET', dataType: 'json', success: function (res) { html_1 = res.url; if (html_1) { html_1 = '<div class="img-area"><img class="my-photo" alt="loading" code-snippet_outer"> html_1 += '"/></div>'; $('#container').append(html_1); window.bookID = res.book_id; window.chapterID = res.chapter_id; window.page = res.page_id; console.log('====', bookID, chapterID, page); i -= 1; if (i) { pictuer(i) } } else { $('#container').append('<h1>没有了</h1>'); return null } }        }); });</script></body>