-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1532 lines (1066 loc) · 272 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.9.0">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="dns-prefetch" href="//qiangck.club">
<title>贾小强的博客</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="description" content="在痛苦中成长,在成长中感受痛苦">
<meta name="keywords" content="javascript,nodejs,vue,react,html,webpack,fe,开发,Developer,js">
<meta property="og:type" content="website">
<meta property="og:title" content="贾小强的博客">
<meta property="og:url" content="//qiangck.club/index.html">
<meta property="og:site_name" content="贾小强的博客">
<meta property="og:description" content="在痛苦中成长,在成长中感受痛苦">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="贾小强的博客">
<meta name="twitter:description" content="在痛苦中成长,在成长中感受痛苦">
<link rel="alternative" href="/atom.xml" title="贾小强的博客" type="application/atom+xml">
<link rel="icon" href="/favicon.ico">
<link rel="stylesheet" type="text/css" href="/./main.bef2e8.css">
<style type="text/css">
#container.show {
background: linear-gradient(200deg,#a0cfe4,#e8c37e);
}
</style>
</head>
</html>
<body>
<div id="container" q-class="show:isCtnShow">
<canvas id="anm-canvas" class="anm-canvas"></canvas>
<div class="left-col" q-class="show:isShow">
<div class="overlay" style="background: #4d4d4d"></div>
<div class="intrude-less">
<header id="header" class="inner">
<a href="/" class="profilepic">
<img src="/images/face.jpeg" class="js-avatar">
</a>
<hgroup>
<h1 class="header-author"><a href="/">qiangck</a></h1>
</hgroup>
<p class="header-subtitle">一个从未被承认的少年</p>
<nav class="header-menu">
<ul>
<li><a href="/">主页</a></li>
</ul>
</nav>
<nav class="header-smart-menu">
<a q-on="click: openSlider(e, 'innerArchive')" href="javascript:void(0)">所有文章</a>
<a q-on="click: openSlider(e, 'aboutme')" href="javascript:void(0)">关于我</a>
</nav>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/qiangck" title="github"><i class="icon-github"></i></a>
<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/jia-zi-qiang-31/activities" title="zhihu"><i class="icon-zhihu"></i></a>
</div>
</nav>
</header>
</div>
</div>
<div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
<nav id="mobile-nav">
<div class="overlay js-overlay" style="background: #4d4d4d"></div>
<div class="btnctn js-mobile-btnctn">
<div class="slider-trigger list" q-on="click: openSlider(e)"><i class="icon icon-sort"></i></div>
</div>
<div class="intrude-less">
<header id="header" class="inner">
<div class="profilepic">
<img src="/images/face.jpeg" class="js-avatar">
</div>
<hgroup>
<h1 class="header-author js-header-author">qiangck</h1>
</hgroup>
<p class="header-subtitle"><i class="icon icon-quo-left"></i>一个从未被承认的少年<i class="icon icon-quo-right"></i></p>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/qiangck" title="github"><i class="icon-github"></i></a>
<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/jia-zi-qiang-31/activities" title="zhihu"><i class="icon-zhihu"></i></a>
</div>
</nav>
<nav class="header-menu js-header-menu">
<ul style="width: 50%">
<li style="width: 100%"><a href="/">主页</a></li>
</ul>
</nav>
</header>
</div>
<div class="mobile-mask" style="display:none" q-show="isShow"></div>
</nav>
<div id="wrapper" class="body-wrap">
<div class="menu-l">
<div class="canvas-wrap">
<canvas data-colors="#eaeaea" data-sectionHeight="100" data-contentId="js-content" id="myCanvas1" class="anm-canvas"></canvas>
</div>
<div id="js-content" class="content-ll">
<article id="post-Html5语音播报" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2019/08/31/Html5语音播报/">Html5语音播报</a>
</h1>
<a href="/2019/08/31/Html5语音播报/" class="archive-article-date">
<time datetime="2019-08-31T07:49:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2019-08-31</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="一个需求引发的实践"><a href="#一个需求引发的实践" class="headerlink" title="一个需求引发的实践"></a>一个需求引发的实践</h3><p> 需求:供应商为了减少订单的丢失率,想在SaaS平台增加试试订单语音播报功能</p>
<p> 技术方案:由后台使用第三方服务,将文案转化成音频文件并保存在服务器,生成音频地址返回给前端,前端使用Audio标签对音频文件进行播放。由于开发工期和使用三方服务的使用成本考虑,考虑由前端来处理语音播放问题,后台只处理订单信息。</p>
<p> 最终方案:使用Html5 Web Speech API</p>
<h3 id="API使用"><a href="#API使用" class="headerlink" title="API使用"></a>API使用</h3><p> 1、属性</p>
<p> SpeechSynthesis.paused 是否为暂停<br> SpeechSynthesis.pending 是否有未完成播放<br> SpeechSynthesis.speaking 是否正在播放</p>
<p> 2、方法</p>
<p> cancel 取消<br> getVoices 返回设备可播放语音列表<br> pause 暂停<br> resume 重启<br> speak 播放,接收SpeechSynthesisUtterance实例</p>
<h3 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h3><p> 1、首先简单封装一下使用方法</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">VoicePlay</span> </span>{</span><br><span class="line"> <span class="keyword">constructor</span> () {</span><br><span class="line"> <span class="keyword">this</span>.volume = <span class="number">1</span></span><br><span class="line"> <span class="keyword">this</span>.speechSynthesis = <span class="built_in">window</span>.speechSynthesis</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 简单使用,配置默认写死</span></span><br><span class="line"> speak (text, callback) {</span><br><span class="line"> <span class="keyword">let</span> utterance = <span class="keyword">new</span> SpeechSynthesisUtterance()</span><br><span class="line"> utterance.text = text</span><br><span class="line"> utterance.lang = <span class="string">'zh-CN'</span></span><br><span class="line"> utterance.volume = <span class="keyword">this</span>.volume</span><br><span class="line"> utterance.onend = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> callback && callback()</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 添加到队列</span></span><br><span class="line"> <span class="keyword">this</span>.speechSynthesis.speak(utterance)</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 播放</span></span><br><span class="line"> play (message, callback) {</span><br><span class="line"> <span class="keyword">this</span>.speak(message, callback)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 停止</span></span><br><span class="line"> stop () {</span><br><span class="line"> <span class="keyword">this</span>.speechSynthesis.cancel()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 静音</span></span><br><span class="line"> mute (value) {</span><br><span class="line"> <span class="keyword">this</span>.volume = value || <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 是否播放</span></span><br><span class="line"> isPlaying () {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.speechSynthesis.speaking</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 2、由于订单信息可能会同时返回很多条,所以需要生成一个队列来进行逐条播放</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">voicePlay</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> queues = []</span><br><span class="line"> <span class="keyword">let</span> fn = <span class="function"><span class="keyword">function</span> (<span class="params">index</span>) </span>{</span><br><span class="line"> <span class="comment">// 显示模态窗</span></span><br><span class="line"> VoicePlay.play(<span class="comment">/* 需要播放的内容 */</span>, () => {</span><br><span class="line"> <span class="keyword">if</span> (queues[index + <span class="number">1</span>]) {</span><br><span class="line"> fn(index + <span class="number">1</span>)</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> VoicePlay.stop()</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 关闭模态窗</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> fn(<span class="number">0</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 3、加个定时器轮询接口,拿订单数据,插入到队列中,如果有新消息停止播放清空队列重新播放新消息。</p>
<h3 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h3><p> 简单的消息播放实现了,SpeechSynthesis属性其实就是调用本地TTS语音引擎进行播放的,如果window系统不能正常播放,很有可能是本地卸载了或不存在要播放的语言包。SpeechSynthesis属性的兼容还可以,除了IE浏览器不支持外,其他大部分的浏览器都是支持的,如果想支持IE浏览器,可以使用ActiveX控件进行支持或者使用百度的接口。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text="</span> + <span class="built_in">encodeURI</span>(text)</span><br></pre></td></tr></table></figure>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color1">HTML5</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/JavaScript//" class="article-tag-list-link color1">JavaScript</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2019/08/31/Html5语音播报/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-前端异常监控思考" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/12/20/前端异常监控思考/">前端异常监控思考</a>
</h1>
<a href="/2018/12/20/前端异常监控思考/" class="archive-article-date">
<time datetime="2018-12-20T09:00:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2018-12-20</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="什么是前端代码异常"><a href="#什么是前端代码异常" class="headerlink" title="什么是前端代码异常"></a>什么是前端代码异常</h3><p> 前端代码异常分两种,1、代码语法错误 2、代码运行时产生错误,第一种错误基本上在项目build的时候就能避免,但是第二种可能无法测试出来,在上线后很难发现,只有用户使用在特殊情况使用时才可能测试出错误。例如:约定好的接口返回数据是个Array格式,但是因为没有做好异常处理导致了错误的发生。</p>
<blockquote>
<p>null.map() //error</p>
</blockquote>
<h3 id="如何捕获异常"><a href="#如何捕获异常" class="headerlink" title="如何捕获异常"></a>如何捕获异常</h3><p> 1、主动判断</p>
<p> 这个很好理解,就是开发者认为执行过程中某处可能会发上错误,预判断错误可能发生的位置,这个考验程序员的基本功。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> format = <span class="function"><span class="params">num</span> =></span> {</span><br><span class="line"> <span class="comment">// 一些对入参的处理内容</span></span><br><span class="line"> <span class="keyword">return</span> num</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">typeof</span> format() !== <span class="string">'number'</span>) {</span><br><span class="line"> <span class="comment">// 可以执行错误内容上传动作</span></span><br><span class="line"> <span class="built_in">console</span>.error(<span class="string">'错误啦,赶紧看看'</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 2、try…catch</p>
<p> 这个也是工程师经常使用的,比如使用async的时候或者JSON.parse()的时候,这个方式避免了页面挂掉的风险,不过也是需要程序员单独处理。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="built_in">JSON</span>.parse()</span><br><span class="line">} <span class="keyword">catch</span> (err) {</span><br><span class="line"> <span class="comment">// 可以执行错误内容上传动作</span></span><br><span class="line"> <span class="built_in">console</span>.error(err, <span class="string">'转换格式错误啦'</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 3、window.onerror</p>
<p> 这个方法浏览器很早就支持了,能够捕获全局的错误,大家也不用考虑兼容问题,但是需要考虑浏览器返回的堆栈的不同,这后面说。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">window</span>.onerror = <span class="function">(<span class="params">message, source, lineno, colno, error</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.error(message, <span class="string">'有错误及时检查啊'</span>)</span><br><span class="line"> <span class="comment">// message:错误信息(字符串)</span></span><br><span class="line"> <span class="comment">// source:发生错误的脚本URL(字符串)</span></span><br><span class="line"> <span class="comment">// lineno:发生错误的行号(数字)</span></span><br><span class="line"> <span class="comment">// colno:发生错误的列号(数字)</span></span><br><span class="line"> <span class="comment">// error:Error对象(对象)</span></span><br><span class="line"> <span class="comment">// 若该函数返回true,则阻止执行默认事件处理函数。</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 这三种方式如果想收集到所有的错误,用第三种方式还是比较理想的,前两种方式再某种情况下也是可以使用的,比较灵活可控,但是我们需要的是一种SDK的植入方式来捕获错误,所以还是需要获取到所有的错误的。JavaScript环境下执行脚本的时候,一旦发现错误,不管目前的堆栈有多深,不管代码运行到了何处,直接跑到顶层或者 try..catch 捕获的那一层。</p>
<h3 id="window-onerror使用"><a href="#window-onerror使用" class="headerlink" title="window.onerror使用"></a>window.onerror使用</h3><p> window.onerror方法会返回大部分浏览器会返回错误信息,错误地址,错误代码的行、列数和堆栈对象,虽然这个方法没有什么兼容性,但是他的返回参数再各个浏览器下会有差异,在这里只阐述现代浏览器,注意是现代浏览器,如果有对IE感兴趣或者需求的话,可以自己测试一下,IE10以下是没有堆栈信息的,需要使用特殊方式获取。</p>
<blockquote>
<p>window.event && window.event.errorCharacter</p>
</blockquote>
<p> 现代浏览器中也分了三种种情况:</p>
<p> 1、正常返回所有参数,但是其中的行数、列数和地址是错误的,所有需要从堆栈中获取准确的错误信息,具体的堆栈信息也是有不同的,这个下面具体说明。</p>
<p> 2、Android手机下或部分浏览器下没有返回堆栈信息,不过还好里面返回的错误行数列数等信息是比较准确的,所以只能返回这些信息来判断具体的错误内容。</p>
<p> 3、还有一种比较特殊的情况就是获取跨域的脚本错误时候,浏览器为了<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=363897" target="_blank" rel="noopener">避免信息泄露</a>message会返回‘Script error’并且不会拿到任何可用的错误信息,这个下面具体说明一下。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> ONERROR = <span class="built_in">window</span>.onerror</span><br><span class="line"><span class="built_in">window</span>.onerror = <span class="function">(<span class="params">msg, source, lineno, colno, errorObj</span>) =></span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">let</span> message = msg ? msg.toLowerCase() : <span class="string">''</span></span><br><span class="line"> <span class="keyword">let</span> _err = <span class="literal">null</span></span><br><span class="line"> <span class="keyword">if</span> (!errorObj || message.indexOf(<span class="string">'script error'</span>) > <span class="number">0</span>) {</span><br><span class="line"> send({</span><br><span class="line"> message: message,</span><br><span class="line"> url: source,</span><br><span class="line"> row: lineno,</span><br><span class="line"> col: colno</span><br><span class="line"> })</span><br><span class="line"> ONERROR && ONERROR.apply(<span class="built_in">window</span>, <span class="built_in">arguments</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (errorObj && errorObj.stack) {</span><br><span class="line"> <span class="comment">// 格式化堆栈信息</span></span><br><span class="line"> _err = formatStackError(errorObj)</span><br><span class="line"> }</span><br><span class="line"> send({</span><br><span class="line"> url: _err.url || source,</span><br><span class="line"> col: _err.col || colno,</span><br><span class="line"> row: _err.row || lineno,</span><br><span class="line"> message: _err.message || message</span><br><span class="line"> })</span><br><span class="line"> ONERROR && ONERROR.apply(<span class="built_in">window</span>, <span class="built_in">arguments</span>)</span><br><span class="line"> } <span class="keyword">catch</span> (err) {</span><br><span class="line"> ONERROR && ONERROR.apply(<span class="built_in">window</span>, <span class="built_in">arguments</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="onerror堆栈信息"><a href="#onerror堆栈信息" class="headerlink" title="onerror堆栈信息"></a>onerror堆栈信息</h3><p> 堆栈信息的内容也可以分为三种情况,哎~~浏览器厂商真的是不能让人消停下来</p>
<p> 1、部分浏览器的堆栈对象里面没有行和列的信息,只能从堆栈对象里面的stack属性解析出来,url信息需要使用正则表达式解析。</p>
<p> 2、Firefox和Chrome的stack属性也有所不一样,里面的行和列分别为</p>
<blockquote>
<p>(columnNumber,lineNumber)|| (column,line)</p>
</blockquote>
<p> 3、部分浏览器是没有stack属性的,这样就只能拿到message了,头疼。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">formatStackError</span>(<span class="params">errorObj</span>) </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">if</span> (errorObj.stack) {</span><br><span class="line"> <span class="keyword">const</span> col = errorObj.column || errorObj.columnNumber</span><br><span class="line"> <span class="keyword">const</span> row = errorObj.line || errorObj.lineNumber</span><br><span class="line"> <span class="keyword">let</span> message = errorObj.message</span><br><span class="line"> <span class="keyword">let</span> stackCol = <span class="literal">null</span></span><br><span class="line"> <span class="keyword">let</span> stackRow = <span class="literal">null</span></span><br><span class="line"> <span class="keyword">let</span> stackText = <span class="string">''</span></span><br><span class="line"> <span class="keyword">let</span> url = errorObj.stack.match(<span class="regexp">/https?:\/\/[^\n]+/</span>)</span><br><span class="line"> url = url ? url[<span class="number">0</span>] : <span class="string">''</span></span><br><span class="line"> <span class="keyword">const</span> rowsAndCols = url.match(<span class="regexp">/:(\d+):(\d+)/</span>)</span><br><span class="line"> <span class="keyword">if</span> (rowsAndCols && rowsAndCols.length >= <span class="number">3</span>) {</span><br><span class="line"> [stackText, stackCol, stackRow] = rowsAndCols</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> message: message,</span><br><span class="line"> col: <span class="built_in">Number</span>(col || stackCol),</span><br><span class="line"> row: <span class="built_in">Number</span>(row || stackRow),</span><br><span class="line"> url: url.replace(stackText, <span class="string">''</span>) || url</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (errorObj.name && errorObj.message && errorObj.description) {</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> message: <span class="built_in">JSON</span>.stringify(errorObj)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (err) {</span><br><span class="line"> <span class="keyword">return</span> errorObj</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 这个处理堆栈信息也可以简单的直接把stack的内容json后上报上去</p>
<h3 id="跨域"><a href="#跨域" class="headerlink" title="跨域"></a>跨域</h3><p> 跨域资源使用window.onerror捕获错误应该是无解的,没办法浏览器限制的,网上的比较好的办法就是使用anonymous属性,这个属性也是有副作用的,需要服务器配合的并且Safari浏览器是不支持muted errors的,所以这个不是一个很优雅的解决办法。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><script type=<span class="string">"text/javascript"</span> src=<span class="string">"https://abc/***.js"</span> crossorigin=<span class="string">"anonymous"</span>><span class="xml"><span class="tag"></<span class="name">script</span>></span></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>服务器要返回的头信息包括:Access-Control-Allow-Origin: *</p>
</blockquote>
<p> 现在比较好的解决方案就是使用try…catch对固定函数做切片处理,但是这样的就比较不够灵活了。</p>
<h3 id="sourceMap"><a href="#sourceMap" class="headerlink" title="sourceMap"></a>sourceMap</h3><p> 现在的前端工程大部分的都是被打包压缩的,这样对捕获错误带来了困难,因为捕获到的错误都是1行1000+列,根本无法真正的知道具体错误的内容,这样就需要对打包后的文件通过sourceMap文件进行定位,可以使用<a href="https://github.com/mozilla/source-map" target="_blank" rel="noopener">source-map</a>对压缩都的文件今天读取。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">formatSourceMap</span>(<span class="params">fileName, line, column</span>) </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">const</span> content = <span class="keyword">await</span> fs.readJson(fileName)</span><br><span class="line"> <span class="keyword">const</span> sources = content.sources</span><br><span class="line"> sources.forEach(<span class="function"><span class="params">element</span> =></span> {</span><br><span class="line"> sourcesPathMap[fixPath(element)] = element</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">const</span> consumer = <span class="keyword">await</span> <span class="keyword">new</span> sourceMap.SourceMapConsumer(content)</span><br><span class="line"> <span class="keyword">const</span> lookup = {</span><br><span class="line"> line: <span class="built_in">parseInt</span>(line),</span><br><span class="line"> column: <span class="built_in">parseInt</span>(column)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">const</span> result = consumer.originalPositionFor(lookup)</span><br><span class="line"> <span class="keyword">const</span> originSource = sourcesPathMap[result.source]</span><br><span class="line"> <span class="keyword">const</span> sourcesContent = content.sourcesContent[sources.indexOf(originSource)]</span><br><span class="line"> result.sourcesContent = sourcesContent</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> } <span class="keyword">catch</span> (err) {</span><br><span class="line"> <span class="keyword">return</span> err</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 这里需要发布的时候把sourceMap文件上传到服务器,上报日志到服务器如果是压缩后的代码,就去服务器找到对应的sourceMap文件进行读取。</p>
<h3 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h3><ul>
<li><a href="https://segmentfault.com/a/1190000011041164" target="_blank" rel="noopener">window.onerror各浏览器下表现总结</a></li>
</ul>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">监控</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/JavaScript//" class="article-tag-list-link color1">JavaScript</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2018/12/20/前端异常监控思考/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-放弃npm拥抱yarn" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/12/28/放弃npm拥抱yarn/">放弃npm拥抱yarn</a>
</h1>
<a href="/2016/12/28/放弃npm拥抱yarn/" class="archive-article-date">
<time datetime="2016-12-28T15:50:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2016-12-28</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="yarn介绍"><a href="#yarn介绍" class="headerlink" title="yarn介绍"></a>yarn介绍</h3><p> Yarn 是Facebook最近发布的一款依赖包安装工具. 官方认为其快速, 安全, 可靠。你下载的包将不再重新下载。而且确保在不同系统中可以正常工作。(<strong>Yarn is a package manager for your code. It allows you to use and share code with other developers from around the world. Yarn does this quickly, securely, and reliably so you don’t ever have to worry.</strong>)</p>
<h3 id="yarn优点"><a href="#yarn优点" class="headerlink" title="yarn优点"></a>yarn优点</h3><ul>
<li>一致性:Yarn允许使用某个lockfile来保证团队中的所有人使用相同版本的npm依赖包,这一点会大大减少因为某个人系统本身问题而导致的Bug</li>
<li>多样性: Yarn还允许用户将npm包以tar.gz形式打包上传到版本控制系统中,这一点能够利用NPM包本身已经对不同版本的Node或者操作系统做了容错这一特性</li>
<li>离线: Yarn允许离线安装某些依赖,这点对于CI系统特别适用。CI系统就不需要保证有稳定的网络连接,特别是在有墙的地方</li>
<li>速度: Yarn采用了新的算法来保证速度, 比NPM快到2~7倍, 同时也允许使用离线包的方式本地安装依赖</li>
<li>安全: 下载前会检查签名及包的完整性</li>
<li>网络优化 :力求网络资源最大利用化,让资源下载完美队列执行,避免大量的无用请求,下载失败会自动重新请求,避免整个安装过程失败</li>
<li>扁平化: 对于不匹配的依赖版本的包创立一个独立的包,避免创建重复的</li>
<li>缓存:缓存已经下载过的包,避免重复下载</li>
</ul>
<h3 id="yarn命令"><a href="#yarn命令" class="headerlink" title="yarn命令"></a>yarn命令</h3><p> <code>yarn init</code>: 初始化某个项目<br> <code>yarn install/link</code>: 默认的安装依赖操作<br> <code>yarn add taco</code>: 安装某个依赖,并且默认保存到package<br> <code>yarn remove taco</code>: 移除某个依赖项目<br> <code>yarn add taco —dev</code>: 安装某个开发时依赖项目<br> <code>yarn upgrade taco</code>: 更新某个依赖项目<br> <code>yarn global add taco</code>: 安装某个全局依赖项目<br> <code>yarn publish/login/logout</code>: 发布/登录/登出,一系列NPM Registry操作<br> <code>yarn run/test</code>: 运行某个命令</p>
<h3 id="yarn安装"><a href="#yarn安装" class="headerlink" title="yarn安装"></a>yarn安装</h3><p> 这里我只说mac的安装方法,win安装较为简单,可以使用npm的方式安装。</p>
<p> 1.安装Homebrew包管理工具,方便快捷,一条指令即可安装完成。</p>
<blockquote>
<p>/usr/bin/ruby -e “$(curl -fsSL <a href="https://raw.githubusercontent.com/Homebrew/install/master/install)"" target="_blank" rel="noopener">https://raw.githubusercontent.com/Homebrew/install/master/install)"</a></p>
</blockquote>
<p> 2.安装yarn。<br> <code>brew update</code><br> <code>brew install yarn</code></p>
<p> 3.验证安装是否完成,如果有显示版本号说明安装完成。<br> <code>yarn --version</code></p>
<h3 id="开始使用yarn"><a href="#开始使用yarn" class="headerlink" title="开始使用yarn"></a>开始使用yarn</h3><p> 如果已有repo,则删除node_modules,使用“yarn”命令进行重新安装;如果新repo则直接使用“yarn“命令安装,可以对npm项目进行无缝衔接<br> <code>rm -rf node_modules</code><br> <code>yarn</code></p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">yarn</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2016/12/28/放弃npm拥抱yarn/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-HTML5-WebSocket介绍" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/06/15/HTML5-WebSocket介绍/">HTML5 WebSocket介绍</a>
</h1>
<a href="/2016/06/15/HTML5-WebSocket介绍/" class="archive-article-date">
<time datetime="2016-06-15T08:50:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2016-06-15</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>WebSocket是一种基于ws协议的技术,它可以建立全双工连接,常见于浏览器,但是不受平台限制,这里只介绍浏览器相关的内容。</p>
<h3 id="浏览器支持"><a href="#浏览器支持" class="headerlink" title="浏览器支持"></a>浏览器支持</h3><table>
<thead>
<tr>
<th>Chrome</th>
<th>Firefox</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
</thead>
<tbody>
<tr>
<td> >16</td>
<td>>11</td>
<td>>10</td>
<td>>12.1</td>
<td>>7</td>
</tr>
</tbody>
</table>
<h3 id="请求"><a href="#请求" class="headerlink" title="请求"></a>请求</h3><p> <code>ws</code>开头是普通的websocket连接,wss是安全的websocket连接,类似于https。</p>
<blockquote>
<p><strong> 客户端到服务端 </strong><br>GET /echo HTTP/1.1<br>Upgrade: WebSocket<br>Connection: Upgrade<br>Host: 127.0.0.1:9999<br>Origin: <a href="http://127.0.0.0.1" target="_blank" rel="noopener">http://127.0.0.0.1</a></p>
</blockquote>
<blockquote>
<p><strong> 服务端到客户端 </strong><br>HTTP/1.1 101 Web Socket Protocol Handshake<br>Upgrade: WebSocket<br>Connection: Upgrade<br>WebSocket-Origin: <a href="http://127.0.0.0.1" target="_blank" rel="noopener">http://127.0.0.0.1</a><br>WebSocket-Location: ws://127.0.0.1:9999</p>
</blockquote>
<h3 id="WebSocket-服务器端"><a href="#WebSocket-服务器端" class="headerlink" title="WebSocket 服务器端"></a>WebSocket 服务器端</h3><ul>
<li>Kaazing WebSocket Gateway:一个 Java 实现的 WebSocket Server</li>
<li>mod_pywebsocket:一个 Python 实现的 WebSocket Server</li>
<li>Netty:一个 Java 实现的网络框架其中包括了对 WebSocket 的支持</li>
<li>node.js:一个 Server 端的 JavaScript 框架提供了对 WebSocket 的支持</li>
</ul>
<h3 id="WebSocket-应用"><a href="#WebSocket-应用" class="headerlink" title="WebSocket 应用"></a>WebSocket 应用</h3><p> 1.创建一个 WebSocket 对象</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ws = <span class="keyword">new</span> WebSocket(<span class="string">"ws://127.0.0.1:9999"</span>, protocols);</span><br></pre></td></tr></table></figure>
<p> <strong>protocols</strong>【可选】:可以是一个单个的协议名字字符串或者包含多个协议名字字符串的数组。</p>
<p> 一旦连接建立(也就是说 readyState 变成 OPEN),ws 将会告诉你服务器选择了哪一种协议。</p>
<table>
<thead>
<tr>
<th>状态readyState</th>
<th>值</th>
<th>介绍</th>
</tr>
</thead>
<tbody>
<tr>
<td> CONNECTING</td>
<td>0</td>
<td>连接还没开启。</td>
</tr>
<tr>
<td> OPEN</td>
<td>1</td>
<td>连接已开启并准备好进行通信</td>
</tr>
<tr>
<td> CLOSING</td>
<td>2</td>
<td>连接正在关闭的过程中</td>
</tr>
<tr>
<td> CLOSED</td>
<td>3</td>
<td>连接已经关闭,或者连接无法建立</td>
</tr>
</tbody>
</table>
<p> 2.发送数据到服务器</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ws.onopen = <span class="function"><span class="keyword">function</span> (<span class="params">event</span>) </span>{ ws.send(<span class="string">"sucess"</span>); };</span><br></pre></td></tr></table></figure>
<p> 建立连接的过程是异步的,而且可能会出错,因此刚刚连接就调用 send() 可能会失败。 我们可以设置 onopen 回调函数来确定什么时候连接成功。</p>
<p> 3.使用 JSON 来传输接收数据</p>
<p> 传输: 需要把要传的对象Object转成JSON,<code>JSON.stringify(obj)</code>;<br> 接收: 需要把接受的数据转成对象Object,<code>JSON.parse(JSON)</code>;</p>
<p> 4.事件描述</p>
<ul>
<li>onmessage:一个用于消息事件的事件监听器,这一事件当有消息到达的时候该事件会触发。这个事件会被传入一个名为”message”的对象</li>
<li>onopen:一个用于连接打开事件的事件监听器。当readyState的值变为OPEN的时候会触发该事件。该事件表明这个连接已经准备好接受和发送数据。这个监听器会接受一个名为”open”的事件对象</li>
<li>onclose:用于监听连接关闭事件监听器。当WebSocket对象的readyState状态变为CLOSED时会出发该事件。这个监听器会接收一个叫close的事件对象</li>
<li>onerror:当错误发生时用于监听error事件的事件监听器。会接受一个名为error的event对象</li>
</ul>
<h3 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h3><ul>
<li>在 Gecko 9之前的版本上,UTF-8 文本里的某些非文本字符会导致连接断开,但是现在的 Gecko 已经解决了这个问题。</li>
<li>不要将 WebSockets 用于混合内容环境;不要在 HTTPS 安全页面下创建非安全的 WebSocket 连接,反之亦然。有些浏览器对此是强行禁止的,例如 Firefox 8 和后续版本。</li>
<li>从Gecko 6.0开始,构造器含有前缀,你需要调用 MozWebSocket(),直到 Gecko 8.0 才被支持 WebSocket。</li>
<li>在 Gecko 11.0之前,用send()方法发送的数据被限制在16MB以内。现在数据大小可以达到2 GB。</li>
</ul>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">websocket</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/HTML5//" class="article-tag-list-link color1">HTML5</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2016/06/15/HTML5-WebSocket介绍/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-模块化开发框架Sea-js上手指南" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/05/12/模块化开发框架Sea-js上手指南/">模块化开发框架Sea.js上手指南</a>
</h1>
<a href="/2016/05/12/模块化开发框架Sea-js上手指南/" class="archive-article-date">
<time datetime="2016-05-12T02:05:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2016-05-12</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<blockquote>
<p>Sea.js的目的是追求简单的代码书写和组织方式,Sea.js并没有过多功能而是主要对前端程序的部署结构作出约束,下面我们就来看一下JavaScript的模块化开发框架Sea.js上手指南:</p>
</blockquote>
<p>Sea.js所有源码都存放在 GitHub 上:<a href="https://github.com/seajs/examples,目录结构为:" target="_blank" rel="noopener">https://github.com/seajs/examples,目录结构为:</a></p>
<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">examples/</span><br><span class="line"> |-- sea-modules 存放 seajs、jquery 等文件,这也是模块的部署目录</span><br><span class="line"> |-- static 存放各个项目的 js、css 文件</span><br><span class="line"> | |-- hello</span><br><span class="line"> | |-- lucky</span><br><span class="line"> | `-- todo</span><br><span class="line"> `-- app 存放 html 等文件</span><br><span class="line"><span class="code"> |-- hello.html</span></span><br><span class="line"><span class="code"> |-- lucky.html</span></span><br><span class="line"><span class="code"> `-- todo.html</span></span><br></pre></td></tr></table></figure>
<h3 id="引入seajs主文件"><a href="#引入seajs主文件" class="headerlink" title="引入seajs主文件"></a>引入seajs主文件</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><script src=<span class="string">"js/sea.js"</span>><span class="xml"><span class="tag"></<span class="name">script</span>></span></span></span><br><span class="line"><script type=<span class="string">"text/javascript"</span>></span><br><span class="line"> <span class="comment">// seajs配置项</span></span><br><span class="line"> seajs.config({</span><br><span class="line"> <span class="comment">//设置基本的JS路径(引用外部文件的根目录)</span></span><br><span class="line"> base:<span class="string">"./js"</span>,</span><br><span class="line"> <span class="comment">//设置别名(方便后面引用使用)</span></span><br><span class="line"> alias:{</span><br><span class="line"> <span class="string">"jQuery"</span>:<span class="string">"jquery.js"</span></span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//路径配置(跨目录调用或者目录比较深时使用)</span></span><br><span class="line"> paths: {</span><br><span class="line"> <span class="string">'jQuery'</span>: <span class="string">'http://libs.baidu.com/jquery/2.0.0/'</span></span><br><span class="line"> },</span><br><span class="line"> <span class="comment">//设置文件编码</span></span><br><span class="line"> charset:<span class="string">"utf-8"</span>,</span><br><span class="line"> <span class="comment">//预加载文件</span></span><br><span class="line"> preload:[<span class="string">'jQuery'</span>]</span><br><span class="line"> });</span><br><span class="line"> <span class="comment">// 引用主入口文件</span></span><br><span class="line"> seajs.use([<span class="string">'main'</span>,<span class="string">'jQuery'</span>],<span class="function"><span class="keyword">function</span>(<span class="params">e,$</span>)</span>{</span><br><span class="line"> <span class="comment">//回调函数</span></span><br><span class="line"> alert(<span class="string">"全部加载完成"</span>);</span><br><span class="line"> });</span><br><span class="line"><<span class="regexp">/script></span></span><br></pre></td></tr></table></figure>
<h3 id="seajs主入口文件-main"><a href="#seajs主入口文件-main" class="headerlink" title="seajs主入口文件(main)"></a>seajs主入口文件(main)</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">define(<span class="function"><span class="keyword">function</span>(<span class="params">require, exports, module</span>) </span>{</span><br><span class="line"> <span class="comment">// 主入口文件引入其他文件依赖</span></span><br><span class="line"> <span class="comment">//var testReQ = require('index');</span></span><br><span class="line"> <span class="keyword">var</span> testReQ = <span class="built_in">require</span>.async(<span class="string">'index'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//异步加载回调</span></span><br><span class="line"> alert(<span class="string">"我是异步加载的index的回调函数"</span>);</span><br><span class="line"> });</span><br><span class="line"> <span class="comment">// 运行index释放的接口方法</span></span><br><span class="line"> <span class="comment">// testReQ.testInit();</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 运行index释放的接口方法(module)</span></span><br><span class="line"> testReQ.textFun();</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<h3 id="seajs依赖文件-index"><a href="#seajs依赖文件-index" class="headerlink" title="seajs依赖文件(index)"></a>seajs依赖文件(index)</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">define(<span class="function"><span class="keyword">function</span>(<span class="params">require, exports, module</span>) </span>{</span><br><span class="line"> <span class="comment">// 对外释放接口</span></span><br><span class="line"> exports.testInit = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">"我是一个接口"</span>);</span><br><span class="line"> };</span><br><span class="line"> <span class="comment">// 如果需要释放大量接口,可以使用module</span></span><br><span class="line"> <span class="keyword">var</span> testObj = {</span><br><span class="line"> name:<span class="string">"qiangck"</span>,</span><br><span class="line"> sex:<span class="string">"man"</span>,</span><br><span class="line"> textFun:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">"我是一个使用module.exports的对象方法"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// module.exports接收obj对象</span></span><br><span class="line"> <span class="built_in">module</span>.exports = testObj;</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<h3 id="文件的加载顺序"><a href="#文件的加载顺序" class="headerlink" title="文件的加载顺序"></a>文件的加载顺序</h3><p><img src="/images/pasted-5.png" alt="upload successful"></p>
<p>下面我们从 hello.html 入手,来瞧瞧使用 Sea.js 如何组织代码。</p>
<h3 id="在页面中加载模块"><a href="#在页面中加载模块" class="headerlink" title="在页面中加载模块"></a>在页面中加载模块</h3><p>在 hello.html 页尾,通过 script 引入 sea.js 后,有一段配置代码:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// seajs 的简单配置</span></span><br><span class="line">seajs.config({</span><br><span class="line"> base: <span class="string">"../sea-modules/"</span>,</span><br><span class="line"> alias: {</span><br><span class="line"> <span class="string">"jquery"</span>: <span class="string">"jquery/jquery/1.10.1/jquery.js"</span></span><br><span class="line"> }</span><br><span class="line">})</span><br><span class="line"><span class="comment">// 加载入口模块</span></span><br><span class="line">seajs.use(<span class="string">"../static/hello/src/main"</span>)</span><br></pre></td></tr></table></figure>
<p>sea.js 在下载完成后,会自动加载入口模块。页面中的代码就这么简单。</p>
<h3 id="模块代码"><a href="#模块代码" class="headerlink" title="模块代码"></a>模块代码</h3><p>这个小游戏有两个模块 spinning.js 和 main.js,遵循统一的写法:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 所有模块都通过 define 来定义</span></span><br><span class="line">define(<span class="function"><span class="keyword">function</span>(<span class="params">require, exports, module</span>) </span>{</span><br><span class="line"> <span class="comment">// 通过 require 引入依赖</span></span><br><span class="line"> <span class="keyword">var</span> $ = <span class="built_in">require</span>(<span class="string">'jquery'</span>);</span><br><span class="line"> <span class="keyword">var</span> Spinning = <span class="built_in">require</span>(<span class="string">'./spinning'</span>);</span><br><span class="line"> <span class="comment">// 通过 exports 对外提供接口</span></span><br><span class="line"> exports.doSomething = ...</span><br><span class="line"> <span class="comment">// 或者通过 module.exports 提供整个接口</span></span><br><span class="line"> <span class="built_in">module</span>.exports = ...</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>上面就是 Sea.js 推荐的 CMD 模块书写格式。如果你有使用过 Node.js,一切都很自然。</p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2016/05/12/模块化开发框架Sea-js上手指南/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-favicon-ico重复请求问题" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/04/03/favicon-ico重复请求问题/">favicon.ico重复请求问题</a>
</h1>
<a href="/2016/04/03/favicon-ico重复请求问题/" class="archive-article-date">
<time datetime="2016-04-02T17:44:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2016-04-02</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>favicon.ico图标用于收藏夹图标和浏览器标签上的显示,如果不设置,浏览器会请求网站根目录的这个图标,如果网站根目录也没有这图标会产生 404的请求,并会重复请求,出于优化的考虑,要么就有这个图标,要么就禁止产生这个请求,在移动端下不希望产生favicon.ico的请求,可以在页面的’‘区域,加上如下代码实现屏蔽:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!-- 简洁版 --></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">href</span>=<span class="string">"data:;base64,="</span>/></span></span><br><span class="line"><span class="comment"><!-- 完整版 --></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">href</span>=<span class="string">"data:image/ico;base64,aWNv"</span>/></span></span><br></pre></td></tr></table></figure></p>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">解决方案</a>
</li>
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">meta</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/HTML5//" class="article-tag-list-link color1">HTML5</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2016/04/03/favicon-ico重复请求问题/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-弹性盒模型的简单使用" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2015/11/12/弹性盒模型的简单使用/">弹性盒模型的简单使用</a>
</h1>
<a href="/2015/11/12/弹性盒模型的简单使用/" class="archive-article-date">
<time datetime="2015-11-12T03:36:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2015-11-12</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="基本使用方法"><a href="#基本使用方法" class="headerlink" title="基本使用方法"></a>基本使用方法</h3><p> Flexible Box(弹性盒子)能让页面的分布更合理和方便,这是之前使用常规的布局方式所做不到的。</p>
<p> <img src="/images/pasted-0.png" alt="upload successful"></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"warp"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"modular"</span>></span>1<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"modular"</span>></span>2<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"modular"</span>></span>3<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"modular"</span>></span>4<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>display:flex和display:box有什么区别?</p>
</blockquote>
<p> 前者是flex 2012年的语法,也将是以后标准的语法,大部分浏览器已经实现了无前缀版本。</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.warp</span>{</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100px</span>;</span><br><span class="line"> <span class="comment">/*这个是用来定义伸缩容器,是内联还是块取决于设置的值。*/</span></span><br><span class="line"> <span class="comment">/*这个时候,他的所有子元素将变成flex文档流,称为伸缩项目。*/</span></span><br><span class="line"> <span class="comment">/*---------------------*/</span></span><br><span class="line"> <span class="attribute">display</span>: -webkit-box; <span class="comment">/* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */</span></span><br><span class="line"> <span class="attribute">display</span>: -moz-box; <span class="comment">/* Firefox 17- */</span></span><br><span class="line"> <span class="attribute">display</span>: -webkit-flex; <span class="comment">/* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */</span></span><br><span class="line"> <span class="attribute">display</span>: -moz-flex; <span class="comment">/* Firefox 18+ */</span></span><br><span class="line"> <span class="attribute">display</span>: -ms-flexbox; <span class="comment">/* IE 10 */</span></span><br><span class="line"> <span class="attribute">display</span>: flex; <span class="comment">/* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */</span></span><br><span class="line"> <span class="comment">/*---------------------*/</span></span><br><span class="line"> <span class="comment">/*一起使用box-align 和 box-pack 属性,对子元素进行居中*/</span></span><br><span class="line"> <span class="attribute">-webkit-box-pack</span>:justify;</span><br><span class="line"> <span class="attribute">-webkit-box-align</span>: ustify;</span><br><span class="line"> <span class="attribute">-moz-box-pack</span>:justify;</span><br><span class="line"> <span class="attribute">-moz-box-align</span>:justify;</span><br><span class="line"> <span class="attribute">box-pack</span>:justify;</span><br><span class="line"> <span class="attribute">box-align</span>:justify;</span><br><span class="line"> <span class="comment">/*---------------------*/</span></span><br><span class="line"> <span class="comment">/*定义了伸缩项目放置在伸缩容器的方向*/</span></span><br><span class="line"> <span class="attribute">flex-direction</span>:row;</span><br><span class="line"> <span class="attribute">-webkit-flex-direction</span>:row;</span><br><span class="line"> <span class="comment">/*定义伸缩容器里是单行还是多行显示*/</span></span><br><span class="line"> <span class="attribute">flex-wrap</span>:nowrap;</span><br><span class="line"> <span class="comment">/*flex-direction”和“flex-wrap”属性的缩写版本,默认row nowrap*/</span></span><br><span class="line"> <span class="attribute">flex-flow</span>:row nowrap;</span><br><span class="line"> <span class="comment">/*设置伸缩容器在横向方向上的对齐方式。*/</span></span><br><span class="line"> <span class="attribute">justify-content</span>:center;</span><br><span class="line"> <span class="comment">/*设置伸缩容器在纵向方向上的对齐方式。*/</span></span><br><span class="line"> <span class="attribute">align-items</span>:center;</span><br><span class="line"> <span class="comment">/*当伸缩容器的纵向还有多余空间时,可以用来调准伸缩容器横向在伸缩容器里的对齐方式*/</span></span><br><span class="line"> <span class="attribute">align-content</span>:center;</span><br><span class="line">} </span><br><span class="line"><span class="comment">/*子级*/</span></span><br><span class="line"><span class="selector-class">.warp</span> <span class="selector-class">.modular</span>{</span><br><span class="line"> <span class="attribute">width</span>:<span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">height</span>:<span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">background-color</span>:<span class="number">#eee</span>;</span><br><span class="line"> <span class="attribute">text-align</span>:center;</span><br><span class="line"> <span class="comment">/*设置伸缩项目出現的順序。*/</span></span><br><span class="line"> <span class="attribute">order</span>:-<span class="number">1</span>;</span><br><span class="line"> <span class="comment">/*设置伸缩项目扩展的比例。*/</span></span><br><span class="line"> <span class="attribute">flex-grow</span>:<span class="number">1</span>;</span><br><span class="line"> <span class="comment">/*设置伸缩项目收缩的比例。*/</span></span><br><span class="line"> <span class="attribute">flex-shrink</span>:<span class="number">2</span>;</span><br><span class="line"> <span class="comment">/*设置伸缩项目的伸缩基准值。*/</span></span><br><span class="line"> <span class="attribute">flex-basis</span>:auto;</span><br><span class="line"> <span class="comment">/*flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写*/</span></span><br><span class="line"> <span class="attribute">flex</span>:<span class="number">1</span> <span class="number">2</span> <span class="number">100px</span>;</span><br><span class="line"> <span class="comment">/*用来在单独的伸缩项目上覆写默认的对齐方式。*/</span></span><br><span class="line"> <span class="attribute">align-self</span>:center;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> 直接上代码,写了个Demo便于理解,其中warp为父元素,称为“伸缩容器,modular为子元素,称为“伸缩项目”。</p>
<h3 id="应用场景"><a href="#应用场景" class="headerlink" title="应用场景"></a>应用场景</h3><ul>
<li>Flexbox布局最适合应用程序的组件和小规模的布局,而网格布局更适合那些更大规模的布局。</li>
<li>目前没有浏览器支持 box-flex 属性,Firefox 支持替代的 -moz-box-flex 属性,Safari、Opera 以及 Chrome 支持替代的 -webkit-box-flex 属性。</li>
<li>CSS的columns在伸缩容器上没有效果。</li>
<li><p>float、clear和vertical-align在伸缩项目上没有效果。</p>
<blockquote>
<p>例:移动端导航(居中,左右,自适应居中,自适应竖向排列)</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">type</span>=<span class="string">"text/css"</span>></span><span class="undefined"></span></span><br><span class="line"><span class="css"> <span class="selector-class">.nav</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#00BFFF</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-webkit-box</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-moz-box</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-ms-flexbox</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-webkit-flex</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:flex</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">-webkit-flex-flow</span><span class="selector-pseudo">:row</span> <span class="selector-tag">wrap</span>;</span></span><br><span class="line"><span class="css"> <span class="comment">/*自适应竖向排列*/</span></span></span><br><span class="line"><span class="css"> <span class="selector-tag">-webkit-flex-flow</span><span class="selector-pseudo">:column</span> <span class="selector-tag">wrap</span>;</span></span><br><span class="line"><span class="css"> <span class="comment">/* 所有列面向主轴起始位置靠齐 */</span></span></span><br><span class="line"><span class="css"> <span class="selector-tag">justify-content</span><span class="selector-pseudo">:flex-start</span>;</span></span><br><span class="line"><span class="css"> <span class="comment">/* 所有列面向主轴终点位置靠齐 */</span></span></span><br><span class="line"><span class="css"> <span class="selector-tag">justify-content</span><span class="selector-pseudo">:flex-end</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.nav</span> <span class="selector-tag">a</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">text-decoration</span><span class="selector-pseudo">:none</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:block</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">padding</span><span class="selector-pseudo">:1em</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">color</span>:<span class="selector-id">#fff</span>;</span></span><br><span class="line"><span class="css"> <span class="comment">/*居中平铺*/</span></span></span><br><span class="line"><span class="css"> <span class="selector-tag">flex</span><span class="selector-pseudo">:1</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> @<span class="keyword">media</span> all and (max-width: <span class="number">800px</span>) {</span></span><br><span class="line"><span class="css"> <span class="selector-class">.nav</span>{</span></span><br><span class="line"><span class="css"> <span class="comment">/* 所有列面向主轴两端位置平均分配 */</span></span></span><br><span class="line"><span class="css"> <span class="selector-tag">justify-content</span><span class="selector-pseudo">:space-around</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">style</span>></span></span><br><span class="line"><span class="tag"><<span class="name">ul</span> <span class="attr">class</span>=<span class="string">"nav"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>1<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>2<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>3<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"#"</span>></span>4<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">li</span>></span></span><br><span class="line"><span class="tag"></<span class="name">ul</span>></span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>例:移动端常用自适应布局</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">type</span>=<span class="string">"text/css"</span>></span><span class="undefined"></span></span><br><span class="line"><span class="css"> <span class="selector-class">.wrapper</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-webkit-box</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-moz-box</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-ms-flexbox</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:-webkit-flex</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">display</span><span class="selector-pseudo">:flex</span>; </span></span><br><span class="line"><span class="css"> <span class="selector-tag">-webkit-flex-flow</span><span class="selector-pseudo">:row</span> <span class="selector-tag">wrap</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">flex-flow</span><span class="selector-pseudo">:row</span> <span class="selector-tag">wrap</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.wrapper</span> > *{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">padding</span><span class="selector-pseudo">:10px</span>;</span></span><br><span class="line"><span class="css"> <span class="selector-tag">flex</span><span class="selector-pseudo">:1</span> 100%;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.header</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#FF6347</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.footer</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#90EE90</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.main</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#00BFFF</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.aside-1</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#FFD700</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.aside-2</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">background</span>:<span class="selector-id">#FF69B4</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> @<span class="keyword">media</span> all and (min-width: <span class="number">600px</span>) {</span></span><br><span class="line"><span class="css"> <span class="selector-class">.aside</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">flex</span><span class="selector-pseudo">:1</span> <span class="selector-tag">auto</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> @<span class="keyword">media</span> all and (min-width: <span class="number">800px</span>) {</span></span><br><span class="line"><span class="css"> <span class="selector-class">.main</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">flex</span><span class="selector-pseudo">:3</span> 0<span class="selector-tag">px</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.aside-1</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">order</span><span class="selector-pseudo">:1</span>;</span></span><br><span class="line"><span class="undefined"> } </span></span><br><span class="line"><span class="css"> <span class="selector-class">.main</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">order</span><span class="selector-pseudo">:2</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.aside-2</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">order</span><span class="selector-pseudo">:3</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="css"> <span class="selector-class">.footer</span>{</span></span><br><span class="line"><span class="css"> <span class="selector-tag">order</span><span class="selector-pseudo">:4</span>;</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"> }</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">style</span>></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wrapper"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">header</span> <span class="attr">class</span>=<span class="string">"header"</span>></span>顶部<span class="tag"></<span class="name">header</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">article</span> <span class="attr">class</span>=<span class="string">"main"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span>我在中间显示的文字<span class="tag"></<span class="name">p</span>></span> </span><br><span class="line"> <span class="tag"></<span class="name">article</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aside</span> <span class="attr">class</span>=<span class="string">"aside aside-1"</span>></span>我在左边显示的文字<span class="tag"></<span class="name">aside</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aside</span> <span class="attr">class</span>=<span class="string">"aside aside-2"</span>></span>我在右边显示的文字<span class="tag"></<span class="name">aside</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">footer</span> <span class="attr">class</span>=<span class="string">"footer"</span>></span>底部<span class="tag"></<span class="name">footer</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color3">flexbox</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/css//" class="article-tag-list-link color4">css</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2015/11/12/弹性盒模型的简单使用/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>
<article id="post-Deferred对象与异步编程" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2015/11/03/Deferred对象与异步编程/">Deferred对象与异步编程</a>
</h1>
<a href="/2015/11/03/Deferred对象与异步编程/" class="archive-article-date">
<time datetime="2015-11-03T03:09:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2015-11-03</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>以Deferred方式执行Ajax回调</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">$.ajax(<span class="string">'/test'</span>).done(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>)</span>{</span><br><span class="line"> <span class="comment">//请求成功后的操作</span></span><br><span class="line"> alert(<span class="string">'done1'</span>);</span><br><span class="line">}).done(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//请求成功后的操作</span></span><br><span class="line"> alert(<span class="string">'done2'</span>);</span><br><span class="line">}).fail(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//请求失败后的操作</span></span><br><span class="line"> alert(<span class="string">'fail'</span>);</span><br><span class="line">}).always(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//请求完成后的操作</span></span><br><span class="line"> alert(<span class="string">'always'</span>);</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line">$.ajax(<span class="string">'/test'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//如果成功执行</span></span><br><span class="line"> alert(<span class="string">'success'</span>);</span><br><span class="line">},<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="comment">//如果失败执行</span></span><br><span class="line"> alert(<span class="string">'error'</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<blockquote>
<p>例:Deferred的实现方法</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//常规方式</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">testDeferred</span>(<span class="params"></span>)</span>{</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> val = <span class="built_in">Math</span>.random();</span><br><span class="line"> <span class="keyword">if</span>(val > <span class="number">0.5</span>){</span><br><span class="line"> alert(<span class="string">'done'</span> + val);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> alert(<span class="string">'fail'</span> + val);</span><br><span class="line"> }</span><br><span class="line"> },<span class="number">100</span>);</span><br><span class="line">}</span><br><span class="line"><span class="comment">//使用Deferred方式</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">tt</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> defer = $.Deferred();</span><br><span class="line"> setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> val = <span class="built_in">Math</span>.random();</span><br><span class="line"> <span class="keyword">var</span> > <span class="number">0.5</span> ? defer.resolve(val) : defer.reject(val);</span><br><span class="line"> },<span class="number">100</span>);</span><br><span class="line"> <span class="keyword">return</span> defer;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">tt().done(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>)</span>{</span><br><span class="line"> alert(<span class="string">'done'</span> + data);</span><br><span class="line">}).fail(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>)</span>{</span><br><span class="line"> alert(<span class="string">'fail'</span> + data);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<blockquote>
<p>例:多个请求同时发起(when)</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$.when(</span><br><span class="line"> $.ajax(<span class="string">'/test?err=n&a=1'</span>),</span><br><span class="line"> $.ajax(<span class="string">'/test?err=n&a=2'</span>),</span><br><span class="line"> $.ajax(<span class="string">'/test?err=n&a=3'</span>)</span><br><span class="line">).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">'success'</span>);</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">arguments</span>);</span><br><span class="line">},<span class="function"><span class="keyword">function</span>(<span class="params">promise,statusText,errObj</span>)</span>{</span><br><span class="line"> alert(<span class="string">'error'</span>);</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">arguments</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<blockquote>
<p>例:多个请求一次发起(then)</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$.ajax(<span class="string">'/test?err=n'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">'success'</span>);</span><br><span class="line"> <span class="comment">//如果成功执行,并返回</span></span><br><span class="line"> <span class="keyword">return</span> $.ajax(<span class="string">'/test'</span>);</span><br><span class="line">},<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">'error1'</span>);</span><br><span class="line"> <span class="comment">//如果失败执行,并返回</span></span><br><span class="line"> <span class="keyword">return</span> $.ajax(<span class="string">'/test?a=no'</span>);</span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> alert(<span class="string">'success2'</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
</div>
<div class="article-info article-info-index">
<div class="article-tag tagcloud">
<i class="icon-price-tags icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="javascript:void(0)" class="js-tag article-tag-list-link color1">$.Deferred</a>
</li>
</ul>
</div>
<div class="article-category tagcloud">
<i class="icon-book icon"></i>
<ul class="article-tag-list">
<li class="article-tag-list-item">
<a href="/categories/jQuery//" class="article-tag-list-link color2">jQuery</a>
</li>
</ul>
</div>
<p class="article-more-link">
<a class="article-more-a" href="/2015/11/03/Deferred对象与异步编程/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<aside class="wrap-side-operation">
<div class="mod-side-operation">
<div class="jump-container" id="js-jump-container" style="display:none;">
<a href="javascript:void(0)" class="mod-side-operation__jump-to-top">
<i class="icon-font icon-back"></i>
</a>
<div id="js-jump-plan-container" class="jump-plan-container" style="top: -11px;">
<i class="icon-font icon-plane jump-plane"></i>
</div>
</div>
</div>
</aside>