由于javascript是單執行緒的執行模型,因此為了提高效率就有了異步編程,單執行緒在程式執行時,所走的程式路徑按照連續順序排下來,前面的必須處理好,后面的才會執行, 但是我們也需要類似多執行緒機制的這種執行方式,我們需要異步執行編程,異步執行編程會使得多個任務并發執行, 異步編程可以實作多任務并發執行,指同一時刻內多任務同時進行,邊煮飯,邊燒水,可以同時進行,進而提高效率,
1.回呼函式
回呼函式,就是把任務的第二段單獨寫在一個函式里面,等到重新執行這個任務的時候,就直接呼叫這個函式,
const fs = require('fs')
fs.readFile('/etc/passwd', (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data.toString())
})
回呼函式最大的問題是容易形成回呼地獄,即多個回呼函式嵌套,降低代碼可讀性,增加邏輯的復雜性,容易出錯,
fs.readFile(file1, function (err, data) { fs.readFile(file2, function (err, data) { // }) })
2.promise
為解決回呼函式的不足,就有了Promise,
const fs = require('fs')
const readFileWithPromise = file => {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
readFileWithPromise('/etc/passwd')
.then(data => {
console.log(data.toString())
return readFileWithPromise('/etc/profile')
})
.then(data => {
console.log(data.toString())
})
.catch(err => {
console.log(err)
})
promise 實際上是利用編程技巧將回呼函式的橫向加載,改成縱向加載,達到鏈式呼叫的效果,避免回呼地獄,最大問題是代碼冗余,原來的任務被 promise 包裝了一下,優點是減少代碼嵌套,代碼邏輯清晰,
3.async、await
為了解決 promise 的問題,async、await 在 ES7 中被提了出來
const fs = require('fs')
async function readFile() {
try {
var f1 = await readFileWithPromise('/etc/passwd')
console.log(f1.toString())
var f2 = await readFileWithPromise('/etc/profile')
console.log(f2.toString())
} catch (err) {
console.log(err)
}
}
特點:
1.異步async函式的呼叫,跟普通的函式使用方式一樣;
2.async的用法,它作為一個關鍵字放到函式前面,這樣普通函式就變成了異步函式;
3.異步async函式回傳一個promise物件;
4.async函式配合await使用可以阻塞代碼往下執行,是異步方法,
優點:
1.多個引數傳遞:promise使用then函式只能傳遞一個引數,雖然可以通過包裝成物件來傳遞多個引數,但是會導致傳遞冗余資訊,頻繁的決議又重新組合比較麻煩;而利用async和await可以沒有這個限制,可以當做普通變數的區域變數來處理,也沒有冗余作業;
2.同步和異步一起撰寫:使用promise的時候最好將同步代碼和異步代碼放在不同的then節點中,這樣結構更加清晰;async和await整個書寫習慣都是同步的,不需要糾結同步和異步的區別,當然,異步程序需要包裝成一個promise物件放在await關鍵字后面;
3. 對promise的優化:async和await是基于promise的,是進一步的一種優化,
使用場景:
async和await主要用來處理異步的操作,執行第一步,將執行第一步的結果回傳給第二步使用,在ajax中先拿到一個介面的回傳資料,后使用第一部回傳的資料執行第二步操作的介面呼叫,達到異步操作,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/464072.html
標籤:JavaScript
