1. 程式人生 > >非同步與閉包與fetch 非同步與閉包與fetch

非同步與閉包與fetch 非同步與閉包與fetch

非同步與閉包與fetch

 

js是單執行緒語言,單執行緒就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。

如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO裝置(輸入輸出裝置)很慢(比如Ajax操作從網路讀取資料),不得不等著結果出來,再往下執行。

JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO裝置,掛起處於等待中的任務,先執行排在後面的任務。等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。

於是,所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是,在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務指的是,不進入主執行緒、而進入"任務佇列"(task queue)的任務,只有"任務佇列"通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。

具體來說,非同步執行的執行機制如下。(同步執行也是如此,因為它可以被視為沒有非同步任務的非同步執行。)

 

閉包就是能夠讀取其他函式內部變數的函式。例如在javascript中,只有函式內部的子函式才能讀取區域性變數,所以閉包可以理解成“定義在一個函式內部的函式“。在本質上,閉包是將函式內部和函式外部連線起來的橋樑。

 

fetch使用

複製程式碼
 1 *{
 2             padding: 0px;
 3             margin: 0px;
 4         }
 5         a{
 6             font-size: 18px;
 7             color: rgb(0, 0, 0);
 8             text-decoration: none;
 9             padding: 5px 8px;
10             background-color: rgb(218, 230, 226);
11             border-radius: 4px;
12         }
13         .title{
14             margin: 40px auto;
15             width: 360px;
16             display: flex;
17             justify-content: center;
18             align-items: center;
19         }
20         .title span{
21             margin: 0px 20px;
22         }
23         .asd{
24             max-width: 960px;
25             margin: 100px auto;
26         }
27         .about{
28             position: relative;
29         }
30         .about{
31             color: #fff;
32         }
33         .about .introuduce{
34             position: absolute;
35             left: 60px;
36             top: 70px;
37         }
38         .about .introuduce p{
39             margin: 10px 0px;
40         }
41         .about .introuduce p span{
42             margin-right: 20px;
43         }
44         button{
45             background-color: #4CAF50;
46             border: none;
47             color: white;
48             padding: 10px 15px;
49             text-align: center;
50             text-decoration: none;
51             display: inline-block;
52             font-size: 12px;
53             margin: 4px 2px;
54             cursor: pointer;
55         }
56         .about .mask{
57             width: 200px;
58             height: 100%;
59             left: 0px;
60             top: 0px;
61             position: absolute;
62             background-color: rgba(0, 0, 0, .5);
63         }
64         .work{
65             padding: 4px 8px;
66             border: 1px solid rgb(255, 126, 40);
67             background: rgb(255, 126, 40);
68             border-radius: 6px;
69         }
70         .history{
71             margin: 20px 0px;
72         }
73         .template{
74             display: flex;
75             margin: 20px 0px;
76         }
77         .template .img{
78             margin-right: 20px;
79         }
80         h2{
81             font-size: 20px;
82             margin: 10px 0px;
83         }
84         h4{
85             margin: 8px 0px;
86             font-size: 14px;
87         }
88         .template-skill, .template-equ, .equ-main, .template-main, .template-history{
89             display: none;
90         }
91 
92 
93         .equ-item{
94             display: inline-block;
95             width: 110px;
96             text-align: center;
97         }
複製程式碼 複製程式碼
 1     <div class="asd">
 2         <div class="title">
 3             <a href="https://lol.qq.com/data/info-defail.shtml?id=MissFortune">點選直達官方網頁</a>
 4             <span>賞金獵人</span>
 5             <span>厄運小姐</span>
 6         </div>
 7         <div class="about">
 8             
 9         </div>
10         <div class="history">
11             
12         </div>
13         <div class="skill">
14             <h2>技能介紹</h2>
15             
16         </div>
17         <div class="zhuangbei">
18             <h2>推薦裝備</h2>
19             
20         </div>
21     </div>
22 
23 
24 
25     <!-- main-modal -->
26     <div class="template-main">
27         <div class="mask"></div>
28         <div class="introuduce">
29             <h4>${nickname}</h4>
30             <h1>${name}</h1>
31             <p><span class="work" >射手</span></p>
32             <p><span>物理攻擊</span>   ${}</p>
33             <p><span>魔法攻擊</span>   ${}</p>
34             <p><span>防禦能力</span>   ${}</p>
35             <p><span>上手難度</span>   ${}</p>
36             <div class="down">
37                 <button>購買英雄</button>
38             </div>
39         </div>
40         <div class="bgm">
41             <img src="" alt="">
42         </div>
43     </div>
44 
45     <!-- 背景故事模板 -->
46     <div class="template-history">
47         <h2>背景故事</h2>
48         <div class="story">
49             <p>${story}</p>
50         </div>
51     </div>
52     
53     <!-- 模板 -->
54     <div class="template-skill">
55         <div class="img"><img src="" alt="" ></div>
56         <div class="skill-about">
57             <h3>${skillName}</h3>
58             <p>${skillOne}</p>
59             <p>${skillTwo}</p>
60         </div>
61     </div>
62     <!-- class改為template-equ-box -->
63     <div class="template-equ">
64         <div class="start">
65             <h4>${introduce}</h4>
66             <div class="content">
67 
68             </div>
69         </div>
70     </div>
71     <!-- class改為equ-conten -->
72     <div class="equ-main">
73         <div class="item">
74             <div class="item-top">
75                 <img src="" alt="" >
76             </div>
77             <p>${equName}</p>
78         </div>
79     </div>
複製程式碼

 

複製程式碼
 1 var temMain = document.getElementsByClassName('template-main')[0].innerHTML
 2         var story = document.getElementsByClassName('template-history')[0].innerHTML
 3         var skill = document.getElementsByClassName('template-skill')[0].innerHTML
 4         var equTemp = document.getElementsByClassName('template-equ')[0].innerHTML
 5         var itemEqu = document.getElementsByClassName('equ-main')[0].innerHTML
 6 
 7         var mainBox = document.getElementsByClassName('about')[0]
 8         var storyBox = document.getElementsByClassName('history')[0]
 9         var skillBox = document.getElementsByClassName('skill')[0]
10         var equBox = document.getElementsByClassName('zhuangbei')[0]
11 
12 
13         var templateString = ""
14 
15 
16         // var asd = new XMLHttpRequest()
17         var reqUrl = "https://curtaintan.github.io/tan/a.json"
18         // asd.open( 'GET', reqUrl, true )
19         // asd.responseType = 'json'
20         // asd.send()
21         // asd.onload = function(){
22         //     var res = asd.response
23         //     console.log(res)
24         //     show( res )
25         // }
26 
27 
28 
29         fetch( reqUrl ).then( res => {
30             return handleResponse( res )
31         }).then( res => {
32             console.log( res )
33             show( res )
34         } )
35 
36 
37 
38         //返回資料型別轉換
39         function handleResponse( res ){
40             let contentType = res.headers.get('content-type')
41             console.log( contentType )
42             if( contentType.includes('application/json' ) ){                    //json格式
43                 console.log('-------------資料是json---------------')
44                 return res.json()
45             }else if( contentType.includes('application/json' )){               //xml和文字格式
46                 console.log('-------------資料不是json---------------')
47                 return res.text()
48             }
49         }
50 
51 
52 
53 
54         function show ( data ){
55             //替換main
56             templateString =  temMain.replace("${nickname}", data.nickName)
57             .replace("${name}", data.name)
58             .replace('src=""', 'src="'+ data.headImg +'"')
59             .replace('${}', data.attr.物理攻擊 )
60             .replace('${}', data.attr.魔法攻擊 )
61             .replace('${}', data.attr.防禦能力 )
62             .replace('${}', data.attr.上手難度 )
63             mainBox.innerHTML = templateString
64 
65 
66             //替換故事
67             templateString = story.replace( '${story}', data.story )
68             storyBox.innerHTML = templateString
69 
70 
71             //替換技能
72             for( let i = 0; i < data.skill.length; i ++ ){
73                 templateString = skill.replace( 'src=""', 'src="'+ data.skill[i].image +'"' )
74                 .replace( '${skillName}', data.skill[i].name )
75                 .replace( '${skillOne}', data.skill[i].introduce)
76                 .replace( '${skillTwo}', data.skill[i].twointroduce)
77                 let ss = document.createElement('div')
78                 ss.classList.add('template')
79                 ss.innerHTML = templateString
80                 skillBox.appendChild( ss )
81             }
82 
83 
84             //替換裝備
85             for( let i = 0; i < data.equipment.length; i ++ ){
86                 templateString = equTemp.replace( "${introduce}", data.equipment[i].introduce )
87                 let ss = document.createElement('div')
88                 ss.innerHTML = templateString
89                 for( let j = 0; j < data.equipment[i].equ.length; j ++ ){
90                     templateString = itemEqu.replace('${equName}', data.equipment[i].equ[j].name)
91                     .replace( 'src=""', 'src="'+ data.equipment[i].equ[j].image +'"' )
92                     var son = document.createElement('div')
93                     son.classList.add('equ-item')
94                     son.innerHTML = templateString
95                     ss.appendChild( son )
96                 }
97                 equBox.appendChild( ss )
98             }
99         }
轉自十二月出行的部落格>>>>https://www.cnblogs.com/curtain473/p/10049392.html

js是單執行緒語言,單執行緒就意味著,所有任務需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就不得不一直等著。

如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO裝置(輸入輸出裝置)很慢(比如Ajax操作從網路讀取資料),不得不等著結果出來,再往下執行。

JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO裝置,掛起處於等待中的任務,先執行排在後面的任務。等到IO裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。

於是,所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是,在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務指的是,不進入主執行緒、而進入"任務佇列"(task queue)的任務,只有"任務佇列"通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。

具體來說,非同步執行的執行機制如下。(同步執行也是如此,因為它可以被視為沒有非同步任務的非同步執行。)

 

閉包就是能夠讀取其他函式內部變數的函式。例如在javascript中,只有函式內部的子函式才能讀取區域性變數,所以閉包可以理解成“定義在一個函式內部的函式“。在本質上,閉包是將函式內部和函式外部連線起來的橋樑。

 

fetch使用

複製程式碼
 1 *{
 2             padding: 0px;
 3             margin: 0px;
 4         }
 5         a{
 6             font-size: 18px;
 7             color: rgb(0, 0, 0);
 8             text-decoration: none;
 9             padding: 5px 8px;
10             background-color: rgb(218, 230, 226);
11             border-radius: 4px;
12         }
13         .title{
14             margin: 40px auto;
15             width: 360px;
16             display: flex;
17             justify-content: center;
18             align-items: center;
19         }
20         .title span{
21             margin: 0px 20px;
22         }
23         .asd{
24             max-width: 960px;
25             margin: 100px auto;
26         }
27         .about{
28             position: relative;
29         }
30         .about{
31             color: #fff;
32         }
33         .about .introuduce{
34             position: absolute;
35             left: 60px;
36             top: 70px;
37         }
38         .about .introuduce p{
39             margin: 10px 0px;
40         }
41         .about .introuduce p span{
42             margin-right: 20px;
43         }
44         button{
45             background-color: #4CAF50;
46             border: none;
47             color: white;
48             padding: 10px 15px;
49             text-align: center;
50             text-decoration: none;
51             display: inline-block;
52             font-size: 12px;
53             margin: 4px 2px;
54             cursor: pointer;
55         }
56         .about .mask{
57             width: 200px;
58             height: 100%;
59             left: 0px;
60             top: 0px;
61             position: absolute;
62             background-color: rgba(0, 0, 0, .5);
63         }
64         .work{
65             padding: 4px 8px;
66             border: 1px solid rgb(255, 126, 40);
67             background: rgb(255, 126, 40);
68             border-radius: 6px;
69         }
70         .history{
71             margin: 20px 0px;
72         }
73         .template{
74             display: flex;
75             margin: 20px 0px;
76         }
77         .template .img{
78             margin-right: 20px;
79         }
80         h2{
81             font-size: 20px;
82             margin: 10px 0px;
83         }
84         h4{
85             margin: 8px 0px;
86             font-size: 14px;
87         }
88         .template-skill, .template-equ, .equ-main, .template-main, .template-history{
89             display: none;
90         }
91 
92 
93         .equ-item{
94             display: inline-block;
95             width: 110px;
96             text-align: center;
97         }
複製程式碼 複製程式碼
 1     <div class="asd">
 2         <div class="title">
 3             <a href="https://lol.qq.com/data/info-defail.shtml?id=MissFortune">點選直達官方網頁</a>
 4             <span>賞金獵人</span>
 5             <span>厄運小姐</span>
 6         </div>
 7         <div class="about">
 8             
 9         </div>
10         <div class="history">
11             
12         </div>
13         <div class="skill">
14             <h2>技能介紹</h2>
15             
16         </div>
17         <div class="zhuangbei">
18             <h2>推薦裝備</h2>
19             
20         </div>
21     </div>
22 
23 
24 
25     <!-- main-modal -->
26     <div class="template-main">
27         <div class="mask"></div>
28         <div class="introuduce">
29             <h4>${nickname}</h4>
30             <h1>${name}</h1>
31             <p><span class="work" >射手</span></p>
32             <p><span>物理攻擊</span>   ${}</p>
33             <p><span>魔法攻擊</span>   ${}</p>
34             <p><span>防禦能力</span>   ${}</p>
35             <p><span>上手難度</span>   ${}</p>
36             <div class="down">
37                 <button>購買英雄</button>
38             </div>
39         </div>
40         <div class="bgm">
41             <img src="" alt="">
42         </div>
43     </div>
44 
45     <!-- 背景故事模板 -->
46     <div class="template-history">
47         <h2>背景故事</h2>
48         <div class="story">
49             <p>${story}</p>
50         </div>
51     </div>
52     
53     <!-- 模板 -->
54     <div class="template-skill">
55         <div class="img"><img src="" alt="" ></div>
56         <div class="skill-about">
57             <h3>${skillName}</h3>
58             <p>${skillOne}</p>
59             <p>${skillTwo}</p>
60         </div>
61     </div>
62     <!-- class改為template-equ-box -->
63     <div class="template-equ">
64         <div class="start">
65             <h4>${introduce}</h4>
66             <div class="content">
67 
68             </div>
69         </div>
70     </div>
71     <!-- class改為equ-conten -->
72     <div class="equ-main">
73         <div class="item">
74             <div class="item-top">
75                 <img src="" alt="" >
76             </div>
77             <p>${equName}</p>
78         </div>
79     </div>
複製程式碼

 

複製程式碼
 1 var temMain = document.getElementsByClassName('template-main')[0].innerHTML
 2         var story = document.getElementsByClassName('template-history')[0].innerHTML
 3         var skill = document.getElementsByClassName('template-skill')[0].innerHTML
 4         var equTemp = document.getElementsByClassName('template-equ')[0].innerHTML
 5         var itemEqu = document.getElementsByClassName('equ-main')[0].innerHTML
 6 
 7         var mainBox = document.getElementsByClassName('about')[0]
 8         var storyBox = document.getElementsByClassName('history')[0]
 9         var skillBox = document.getElementsByClassName('skill')[0]
10         var equBox = document.getElementsByClassName('zhuangbei')[0]
11 
12 
13         var templateString = ""
14 
15 
16         // var asd = new XMLHttpRequest()
17         var reqUrl = "https://curtaintan.github.io/tan/a.json"
18         // asd.open( 'GET', reqUrl, true )
19         // asd.responseType = 'json'
20         // asd.send()
21         // asd.onload = function(){
22         //     var res = asd.response
23         //     console.log(res)
24         //     show( res )
25         // }
26 
27 
28 
29         fetch( reqUrl ).then( res => {
30             return handleResponse( res )
31         }).then( res => {
32             console.log( res )
33             show( res )
34         } )
35 
36 
37 
38         //返回資料型別轉換
39         function handleResponse( res ){
40             let contentType = res.headers.get('content-type')
41             console.log( contentType )
42             if( contentType.includes('application/json' ) ){                    //json格式
43                 console.log('-------------資料是json---------------')
44                 return res.json()
45             }else if( contentType.includes('application/json' )){               //xml和文字格式
46                 console.log('-------------資料不是json---------------')
47                 return res.text()
48             }
49         }
50 
51 
52 
53 
54         function show ( data ){
55             //替換main
56             templateString =  temMain.replace("${nickname}", data.nickName)
57             .replace("${name}", data.name)
58             .replace('src=""', 'src="'+ data.headImg +'"')
59             .replace('${}', data.attr.物理攻擊 )
60             .replace('${}', data.attr.魔法攻擊 )
61             .replace('${}', data.attr.防禦能力 )
62             .replace('${}', data.attr.上手難度 )
63             mainBox.innerHTML = templateString
64 
65 
66             //替換故事
67             templateString = story.replace( '${story}', data.story )
68             storyBox.innerHTML = templateString
69 
70 
71             //替換技能
72             for( let i = 0; i < data.skill.length; i ++ ){
73                 templateString = skill.replace( 'src=""', 'src="'+ data.skill[i].image +'"' )
74                 .replace( '${skillName}', data.skill[i].name )
75                 .replace( '${skillOne}', data.skill[i].introduce)
76                 .replace( '${skillTwo}', data.skill[i].twointroduce)
77                 let ss = document.createElement('div')
78                 ss.classList.add('template')
79                 ss.innerHTML = templateString
80                 skillBox.appendChild( ss )
81             }
82 
83 
84             //替換裝備
85             for( let i = 0; i < data.equipment.length; i ++ ){
86                 templateString = equTemp.replace( "${introduce}", data.equipment[i].introduce )
87                 let ss = document.createElement('div')
88                 ss.innerHTML = templateString
89                 for( let j = 0; j < data.equipment[i].equ.length; j ++ ){
90                     templateString = itemEqu.replace('${equName}', data.equipment[i].equ[j].name)
91                     .replace( 'src=""', 'src="'+ data.equipment[i].equ[j].image +'"' )
92                     var son = document.createElement('div')
93                     son.classList.add('equ-item')
94                     son.innerHTML = templateString
95                     ss.appendChild( son )
96                 }
97                 equBox.appendChild( ss )
98             }
99         }
轉自十二月出行的部落格>>>>https://www.cnblogs.com/curtain473/p/10049392.html