非同步與閉包與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