每次只有一個線程其餘線程被阻塞git
簡單來講,就是任務一個接着一個完成。只要一個沒完成其餘被堵塞github
不用阻塞當前線程來等待處理完成,而是容許後續操做,直至其它線程將處理完成,並回調通知此線程。編程
簡單來講,就是任務同時進行,中途可能須要等待其餘任務完成才能進行當前任務。json
js是單線程的,若是有一個任務咱們要花很長時間,那豈不是這以後的代碼全被阻塞了。redux
其實異步編程的發展的目的是愉快地coding:用同步寫法寫異步api
回調函數:異步操做執行完後觸發執行的函數,相似以下格式:promise
$.get("http://xxx.xxxx.com/api",callback);
複製代碼
fetch({
url: "/student",
data:1,
success: function (id) {
fetch({
url: "/score",
data:id,
success: function (score) {
fetch({
url: "/rank",
data:score,
success: function (rank) {
console.log(rank)
}
})
}
})
}
})
複製代碼
Promise 必定程度上解決了回調地獄的問題,Promise 最先由社區提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了Promise對象。Promise對象簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果。從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理。bash
fetch(1).then(id=> {
return fetch(id);
}).then(score => {
return fetch(score);
}).then(rank=> {
console.log(rank)
}).catch(reason => {
console.log(reason);
});
複製代碼
Generator 函數是 ES6 提供的一種異步編程解決方案,整個 Generator 函數就是一個封裝的異步任務,或者說是異步任務的容器。異步操做須要暫停的地方,都用 yield 語句註明。 將函數分割出好多個部分,調用一次next就會繼續向下執行。返回結果是一個迭代器,迭代器有一個next方法。多線程
function my_co (it) {
return new Promise((resolve, reject) => {
function next(data) {
let {value, done} = it.next(data);
if(!done) {
value.then(val => {
next(val);
}, reject);
}else{
resolve(value);
}
}
next();
});
}
function *getData() {
let res=yield fetch('/student',()=>{});
let res1=yield fetch('/score',res1,()=>{});
let res2=yield fetch('/rank',res2,()=>{});
return res2
}
let it=getData()
let id=it.next(it)
let score=it.next(id)
let rank=it.next(score)
my_co(getData()).then(data => {
console.log(data);
});
複製代碼
特別注意:
看上去彷佛咱們平常業務中generator的異步寫法不經常使用,但實際上在某些庫的開發中它有着重要用途。
對!說的就是那個redux-saga
並且仔細想一想還有那個異步編程的方式有這麼大的控制性,想停就停!app
async-await
實際上是一個語法糖,它的實現就是將 Generator函數和自動執行器(co),包裝在一個函數中。
async
至關於用Promise.resolve()
包裹其函數返回值。
await
至關於generator
和promise
的語法糖,至關於yield
,但他以外的同步代碼能夠自動執行
🔔若是沒有依賴性的話也能夠用promise.all
//如上面那個例子
function fetchData(api) {
let result
let url = 'http://localhost:3000'
fetch(url + api, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => {
return res.json()
})
.then((json) => {
console.log(json)
result=json
})
return result
}
async function getData(){
let id=await fetchData('/student')
let score=await fetchData('/score')
let rank=await fetchData('/rank')
}
複製代碼
優勢:
try catch
。async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
複製代碼
git 地址
內含關於四種方式異步編程的例子,歡迎你們試一試👀
附加
: