這期內容當中小編將會給大家帶來有關promise、async、await是什么意思,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
宏任務與微任務都是異步的,其中包括ajax請求、計時器等等,我們初步的了解一下promise,知道他是解決異步的一種方式,那么我們常用的一共有哪幾種方法呢?
因為涉及的知識點比較多,這篇文章主要是講一下,回調函數和promise:
一、回調函數
先上代碼:
function f2() {
console.log('2222')
}
function f1(callback){
console.log('111')
setTimeout(function () {
callback();
}, 5000);
console.log('3333')
}
f1(f2);
先看下打印值是:
111
3333
五秒后2222相當于主線程執行完了,會通過回調函數去調用f2函數,這個沒什么毛病。但是看下下面的例子:
現在我們讀取一個文件,fileReader就是一個異步請求
// 這個異步請求就是通過回調函數的方式獲取的
var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file, 'utf-8',function(err, data){
if(err){
console.log(err)
} else {
console.log(data)
}
})現在看起來也很不錯,但是如果文件上傳出錯了,我們還要在回調里面做判斷,要是我們讀取完這個文件接著要讀取多個文件呢?是不是應該這么寫:
讀取完文件1之后再接著讀取文件2、3
var reader = new FileReader()
var file = input.files[0]
reader.readAsText(file1, 'utf-8',function(err1, data1){
if(err1){
console.log(err1)
} else {
console.log(data1)
}
reader.readAsText(file2, 'utf-8',function(err2, data2){
if(err2){
console.log(err2)
} else {
console.log(data2)
}
reader.readAsText(file3, 'utf-8',function(err3, data3){
if(err3){
console.log(err3)
} else {
console.log(data3)
}
})
})
})這么寫可以實現需求,但是這個代碼的可讀性就比較差,看起來就不那么優雅,也就是我們常說的‘回調地獄’。那么怎么破解這種嵌套式的回調呢?ES6為我們提供了promise:
二、promise
首先我們從字面意思上理解一下什么是promise?promise可以翻譯成承諾、保證,這個地方你可以理解為:
女朋友讓我干了一件事,雖然還沒干完,但是我保證這件事會有一個結果給你,成功(fulfiled)或者失?。╮ejected),還有一個等待狀態(pending)。
還是先上例子
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2000) // 成功以后這個resolve會把成功的結果捕捉到
// reject(2000) // 失敗以后這個reject會把失敗的結果捕捉到
}, 1000)
console.log(1111)
})
promise.then(res => {
console.log(res) // then里面第一個參數就能拿到捕捉到的成功結果
}, err =>{
console.log(res)// then里面第二個參數就能拿到捕捉到的失敗結果
})
打印結果:
1111
2000(一秒以后)1、then鏈式操作
Promise對象的then方法返回一個新的Promise對象,因此可以通過鏈式調用then方法。
then方法接收兩個函數作為參數,第一個參數是Promise執行成功時的回調,第二個參數是Promise執行失敗時的回調,這個上面的例子說的很明白了,第二個參數捕捉的就是失敗的回調。
兩個函數只會有一個被調用,這句話怎么理解呢?
女朋友讓你去做西紅柿雞蛋湯,你要么就去做,要么就不做,叫外賣,肯定沒有第三種選擇。
函數的返回值將被用作創建then返回的Promise對象。這句話應該怎么理解呢?還是上例子:
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2000)
}, 1000)
console.log(1111)
})
promise.then(res => {
console.log(res) // 這個地方會打印捕捉到的2000
return res + 1000 // 這個函數的返回值,返回的就是這個promise對象捕捉到的成功的值
}).then(res => {
console.log(res) //這個地方打印的就是上一個promise對象return的值
})
所以打印順序應該是:
1111
2000
3000剛才我們看到了then接受兩個參數,一個是成功的回調、一個是失敗的回調,看起來好像也不是那么優雅,promise里除了then還提供了catch方法:
2、catch捕捉操作
這個catch就是專門捕捉錯誤的回調的,還是先看例子:
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2000) // 失敗以后這個reject會把失敗的結果捕捉到
}, 1000)
console.log(1111)
})
promise.catch(res => {
console.log(res) // catch里面就能拿到捕捉到的失敗結果
})
打印結果:
1111
2000(一秒以后)除了then和catch之外,promise還有兩個語法,all和race,我們也簡單用一下:
3、all
現在我們有這么一個需求,一共有三個接口A、B、C,必須三個接口都成功以后,才能發起第四個請求,怎么實現呢?
鏈式調用
let getInfoA = new Promise((resolve, reject) => {
console.log('小A開始執行了')
resolve()
}).then(res => {
let getInfoB = new Promise((resolve, reject) => {
console.log('小B開始執行了')
resolve()
}).then(res => {
let getInfoC = new Promise((resolve, reject) => {
console.log('小C開始執行了')
resolve()
}).then(res => {
console.log('全都執行完了!')
})
})
})一層套一層的,好像不是那么優雅
all
let getInfoA = new Promise((resolve, reject) => {
console.log('小A開始執行了')
resolve()
})
let getInfoB = new Promise((resolve, reject) => {
console.log('小B開始執行了')
resolve()
})
let getInfoC = new Promise((resolve, reject) => {
console.log('小C開始執行了')
resolve()
})
Promise.all([getInfoA, getInfoB, getInfoC]).then(res => {
console.log('全都執行完了!')
})接收一個Promise對象組成的數組作為參數,當這個數組所有的Promise對象狀態都變成resolved或者rejected的時候,它才會去調用then方法。非常完美,非常優雅。
4、race
現在又有一個需求,同樣是接口A、B、C,只要有一個響應了,我就可以調接口D,那么怎么實現呢?
1、傳統方式
let getInfoA = new Promise((resolve, reject) => {
console.log('小A開始執行了')
setTimeout((err => {
resolve('小A最快')
}),1000)
}).then(res =>{
console.log(res)
})
let getInfoB = new Promise((resolve, reject) => {
console.log('小B開始執行了')
setTimeout((err => {
resolve('小B最快')
}),1001)
}).then(res =>{
console.log(res)
})
let getInfoC = new Promise((resolve, reject) => {
console.log('小C開始執行了')
setTimeout((err => {
resolve('小C最快')
}),1002)
}).then(res =>{
console.log(res)
})
打印結果
小A開始執行了
小B開始執行了
小C開始執行了
小A最快這個方法得寫三遍,好像也不是那么優雅,一起來看下race應該怎么寫?
2、race
let getInfoA = new Promise((resolve, reject) => {
console.log('小A開始執行了')
setTimeout((err => {
resolve('小A最快')
}),1000)
})
let getInfoB = new Promise((resolve, reject) => {
console.log('小B開始執行了')
setTimeout((err => {
resolve('小B最快')
}),1001)
})
let getInfoC = new Promise((resolve, reject) => {
console.log('小C開始執行了')
setTimeout((err => {
resolve('小C最快')
}),1002)
})
Promise.race([getInfoA, getInfoB, getInfoC]).then(res => {
console.log(res)
})
打印結果
小A開始執行了
小B開始執行了
小C開始執行了
小A最快與Promise.all相似的是,Promise.race都是以一個Promise對象組成的數組作為參數,不同的是,只要當數組中的其中一個Promsie狀態變成resolved或者rejected時,就可以調用.then方法了。
promise是ES6用來解決異步的一個方法,現在用的已經比較廣泛了,像我們經常用的axios,他就是用promise封裝的,用起來非常方便。
上述就是小編為大家分享的promise、async、await是什么意思了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。