新手提问: js 如何处理这种情况 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
kaiwei
V2EX    Javascript

新手提问: js 如何处理这种情况

  •  
  •   kaiwei 2015-11-20 01:24:16 +08:00 2891 次点击
    这是一个创建于 3625 天前的主题,其中的信息可能已经有所发展或是发生改变。
    设想用户在网页点击一个按钮,向后台发送一个请求,例如是想要些数据 A 显示在前台,但是时间有点久,她就点击了另外一个按钮,请求显示数据 B 。 B 很快就返回并显示。此时 A 也到了。问 A 会覆盖 B 吗?(假定想让它们在同一个 div 里显示)。如果会覆盖的话,如何才能让 A 不覆盖 B 。如果不会覆盖的话,这是什么原因。多谢!
    13 条回复    2015-11-20 13:03:27 +08:00
    FrankFang128
        1
    FrankFang128  
       2015-11-20 02:02:40 +08:00
    会覆盖。不想覆盖就加一个序列号,让你知道 A 和 B 是不用的。然后 div 只接受最新的序列号的内容。
    FrankFang128
        2
    FrankFang128  
       2015-11-20 02:03:04 +08:00
    * 让你知道 A 和 B 是不同的
    IamJ
        3
    IamJ  
       2015-11-20 02:19:48 +08:00
    用一个标识变量解决
    imn1
        4
    imn1  
       2015-11-20 02:30:25 +08:00
    用添加而不是改写
    str+=A
    str+=B
    kaiwei
        5
    kaiwei  
    OP
       2015-11-20 02:56:13 +08:00
    @FrankFang128 这个序列号怎么实现?在请求里加上?然后后台返回的时候把它也带上?同时前台有个号码记录最新的序列号应该是几。如果后台返回的号比前台这个号小,就直接忽略。是这样吗?
    kaiwei
        6
    kaiwei  
    OP
       2015-11-20 02:57:07 +08:00
    @IamJ 能否具体说明 或者出处?多谢!
    FrankFang128
        7
    FrankFang128  
       2015-11-20 02:57:41 +08:00
    @kaiwei 恩,请求要把序列号回传。
    FrankFang128
        8
    FrankFang128  
       2015-11-20 02:59:15 +08:00
    方案 2 :每次请求上把上一个请求 abort 掉。这样即使上一个返回了,浏览器也不要了。
    FrankFang128
        9
    FrankFang128  
       2015-11-20 02:59:34 +08:00
    方案 3 :这一次请求没有结束,就不要发起下一次请求。
    FrankFang128
        10
    FrankFang128  
       2015-11-20 02:59:44 +08:00
    方案二最好。
    mcfog
        11
    mcfog  
       2015-11-20 08:16:49 +08:00
    加遮罩层显示 loading 来阻止用户做其他操作也是一种常见的方案
    SilentDepth
        12
    SilentDepth  
       2015-11-20 09:22:37 +08:00
    通常用户界面需要什么东西让用户知道后台有任务在跑,例如 @mcfog 说的加个 Loading 层。如果一次请求的数据并不是一定要显示出来,@FrankFang128 的方案 2 最好。
    sagnitude
        13
    sagnitude  
       2015-11-20 13:03:27 +08:00   1
    补充一下,我觉得保险的话,在发新的请求的时候楼上提到的这些都是要做的:

    1. 尚未发送的请求,取消发送(在发送方法里检查 timestamp )
    2. 已经发送正在等待返回的, abort
    3. 对于请求已经结束,正在处理数据的,用唯一的标识符,在数据处理完的时候拒绝过时的请求的数据
    4. 加 loading 屏幕

    如果只用其中一种或者若干种,还是有风险的,

    因为有时候请求数据的处理是很重的,我经常请求一个数兆的 JSON 文件,然后画到 webgl canvas 里,这时候 JSON 处理根本无法取消,三角化和 geometry 生成也很难取消,只能做多重保险。

    再补充一下,在 Javascript 里,序列号也可以不用加在请求里,也不用服务器返回。由于 js 的回调机制,回调结束之前,那个函数的 scope 仍然是有效的,可以用局部变量和全局变量来做。

    我写了一个简单的例子: https://gist.github.com/sagnitude/b0642604fd1911e016b4

    核心的代码是这样:

    function sendRequest() {
    var timestamp = (new Date()).getTime();

    window.lastRequestTimeStamp = timestamp;

    Request.Dispatch(params, function(result) {
    if (timestamp == window.lastRequestTimeStamp) {
    //do something
    console.log("success! " + timestamp);
    }
    });
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3046 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 12:03 PVG 20:03 LAX 05:03 JFK 08:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86