HTTP子產品介紹
支援http協定的更多特性
不緩存請求和響應
API比較底層處理流相關,資訊解析
HTTP相關概念
回調
将函數作為參數傳到執行函數中,參數函數在執行函數中嵌套執行
function learn(something){
console.log(something);
}
function we(callback,something){
something+=' is cool'
callback(something)
}
//具名函數
we(learn,'Nodejs')
//匿名函數
we(function(something){
console.log(something)
},'hello')
同步/異步
JavaScript中的異步函數
//在指定間隔内執行一次
setTimeout(function(){
alert('1')
},2000)
//在執行間隔内重複執行,但是需要關閉alert,不會彈出N個
setInterval(function(){
alert('1')
},2000)
同步
任務順序執行,等待上一個執行完成再執行下一個
//同步
var c=0
function print(){
console.log(c)
}
function plus(){
setTimeout(function(){
console.log('aaa')
},1000)
c+=1;
}
plus()
print()
異步
setTimeout()不隻是是一個異步函數,它還涉及到了計時器線程
多個setTimeout()函數首先按照先後順序壓入異步函數隊列中
主程式執行完畢後開始執行異步函數隊列
異步隊列中若是setTimeout函數,則放到計時器線程中
在計時器線程中,如果時間相等,則按進入線程的先後順序執行
若有A,B線程,A正在執行,但是B已經到了該執行的時間,那麼B不會執行,直到等待A執行完畢才會執行
若異步隊列中有需要立即執行的函數,那麼久首先執行,A會等待,一次隻執行一個
或者是setTimeout()函數首先放到計時器線程當中,等到指定的時間放入執行隊列當中
每個任務都有多個回調函數,前一個任務執行完畢後不執行下一個任務,而是執行回調函數;後一個任務按照任務的排列順序執行,不會等待上一個任務執行完畢
//異步,任務執行完成後執行回調函數
var c=0
function print(){
console.log(c)
}
function plus(callback){
setTimeout(function(){
c+=1;
callback()
},1000)
console.log('a')
}
plus(print)
有關異步的一個問題:https://www.jianshu.com/p/e5225ba4a025
參考閉包:http://www.jb51.net/article/24101.htm
//以下代碼的輸出是什麼?如何修改
for (var i = 1; i <= 5; i++) {
setTimeout( function(){ //function timer()可以是具名函數
console.log(i);
},i*1000);
}
//輸出5個6:6 6 6 6 6 6
//因為setTimeou函數是異步的,在正文執行完後,i=6的時候開始執行,而且是執行5次,是以列印5個6
錯誤答案:
for (var i = 1; i <= 5; i++) {
setTimeout( function(i){ //function timer()可以是具名函數
console.log(i);
},i*1000);
}
//輸出5 個 undefined;調用匿名函數,沒有傳值,i引用的是參數i的值,i為undefined
正确答案一:
for (var i = 1; i <= 5; i++) {
(function() {
var j = i;
setTimeout( function() {
console.log(j);
},i*1000 ); //這一行将i*1000改為j*1000也行,并不影響
})();
}
//此處用了立即執行函數(function(){})();使setTimeout中函數形成了閉包
//什麼是閉包:當内部函數(setTimeout中的匿名函數) 在定義它的作用域(立即執行函數) 的外部(立即執行函數外部) 被引用時(異步,最後調用,在外部調用)
// 就建立了該内部函數(匿名函數)的閉包
// 如果内部函數(匿名函數)引用了位于外部函數的變量,當外部函數調用完畢後,這些變量在記憶體不會被 釋放,因為閉包需要它們.
//根據閉包的定義,我們面對這個問題的思路:
// 匿名函數function(){ console.log(j) }外要再套一層立即執行函數
// j為引用立即執行函數中的變量
// 通過異步調用匿名函數
正确答案二:使用let塊級作用域形成閉包,不太了解就不說了
for (var i = 1; i <= 5; i++) {
let j = i;
setTimeout(function timer() {
console.log(j);
},j*1000);
}
歸納一下就是:函數裡面有函數,函數外面調用裡面函數;但是函數外面怎麼調用函數裡面的函數呢?
1.使用異步,異步是最後執行;上面的例子是這樣
2.該函數的結果為裡面的函數,先var fn=該函數,然後執行fn,這樣就形成了閉包
I/O
磁盤上資料讀寫
單線程/多線程
一次隻能進行一個請求和響應
多個請求和響應同時進行
阻塞/非阻塞
阻塞:用戶端一直等待服務端響應
非阻塞:請求無響應就去幹别的,過段時間再請求
事件
點選,移動等操作
事件驅動
函數在事件發生的時候執行
基于事件驅動的回調
函數中的回調函數
事件循環
密集任務異步執行放到loop隊列,單線程不斷查詢loop隊列