promise async await
阿新 • • 發佈:2021-01-22
- 首先定義一個函式
let func1 = () => new Promise((resolve, reject) => setTimeout(() => resolve(12345), 1000))
函式func1執行的時候,會返回一個promise物件
let func1 = () => new Promise((resolve, reject) => setTimeout(() => resolve(12345), 1000))
let result = func1()
console.log(result);
- 使用async和await後
let func1 = () => new Promise((resolve, reject) => setTimeout(() => resolve(12345), 1000)) // 當且僅當async修飾函式後,函式內可以使用await,await後面可以跟一個返回promise的函式 async function func2() { // await會拿到resolve結果,是then函式的語法糖 let res = await func1() console.log(res); } func2()
一秒鐘之後打印出12345
- 上面的函式可以寫成這樣的形式
let func1 = () => new Promise((resolve, reject) => setTimeout(() => resolve(12345), 1000))
function func2() {
func1().then(res => console.log(res))
}
func2()
在1秒鐘之後會打印出12345
async + await(是promise + then的語法糖)(可以認為是generator函式的語法糖)
上面兩種方式是等價的,只不過使用async和await可以像同步程式設計一樣整理程式碼邏輯,不想then那樣回撥地獄
async function main() {
try {
var data1 = await query(sql)
...
var data2 = await query(sq2)
...
var data3 = await query(sq3)
} catch(e) {
console.log(e)
}
}
這樣可以對三條語句同時處理錯誤
- 使用async await處理非同步請求
async function get() {
let user = await ajax('/user')
// 等待user請求回來之後,再請求lesson
let lessons = await ajax('/lessons')
// lessons請求回來之後再進行其它的操作
console.log(lessons)
}
get()
- async延時函式
function sleep(delay = 2000) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, delay)
})
}
async function show() {
for (let value of ['hello', 'world', '123']) {
// 延遲2秒之後再列印
await sleep();
console.log(value);
}
}
show()
- class與await結合
如果一個類中包含一個then方法,那麼這個then就會包裝成一個Promise
class User {
constructor(name) {
this.name = name;
}
then(resolve, reject) {
let user = ajax(`http://localhost3000/user?name=${this.name}`);
resolve(user);
}
}
async function get() {
// 名字請求回來之後在列印
let user = await new User('xiaoming');
console.log(user);
}
get()
- await並行執行技巧
function func1() {
return new Promise(resolve => {
setTimeout(() => {
resolve(123)
}, 2000)
})
}
function func2() {
return new Promise(resolve => {
setTimeout(() => {
resolve(456)
}, 2000)
})
}
async function demo() {
let h1 = func1();
let h2 = func2();
let result1 = await h1;
let result2 = await h2;
// 這樣func1和func2就可以一起執行,得到他們的結果後再列印,還可以通過Promise.all實現
console.log(result1, result2);
}
demo()
通過Promise.all實現
function func1() {
return new Promise(resolve => {
setTimeout(() => {
resolve(123)
}, 2000)
})
}
function func2() {
return new Promise(resolve => {
setTimeout(() => {
resolve(456)
}, 2000)
})
}
async function demo() {
let result = await Promise.all([func1(), func2()])
console.log(result);
}
demo()
Promise規範–all
all方法用於監聽多個Promise物件
引數是一個數組,陣列中的每一項都是一個Promise物件
我們可以通過then方法監聽狀態的改變
如果所有的操作都執行成功,才會執行success方法
如果有一個操作執行失敗,則會執行fail方法
不論是成功還是失敗,返回值是陣列,陣列中的每一個成員對應每一個Promise返回的資料
Promise規範–race
race方法用於監聽多個Promise物件
引數是一個數組,陣列中的每一項都是一個Promise物件
我們可以通過then方法監聽狀態的改變(監聽第一個Promise物件狀態的改變)
如果有一個請求執行成功,就會執行success方法
如果有一個請求執行失敗,則會執行fail方法
返回值是狀態改變的時候傳遞的資料
簡單實現Promise
// 實現promise
function MyPromise(callBack) {
// 維護狀態
this.status = 'pendding';
// 儲存回撥函式
this.successArray = [];
this.failArray = [];
// 定義resolve和reject方法
// 成功
let resolve = (value) => {
// 改變狀態
this.status = 'resolved';
// 執行回撥函式
this.successArray.forEach(fn => value = fn(value))
this.successArray = [];
this.value = value;
}
// 失敗
let reject = () => {
this.status = 'rejected';
this.failArray.forEach(fn => value = fn(value))
this.failArray = [];
this.value = value
}
// 執行回撥函式
try {
callBack(resolve, reject);
} catch(e) {
// 有錯誤就失敗了
reject(e);
}
}
// 原型方法
MyPromise.prototype.then = function(success, fail) {
if (this.status === 'padding') {
success && this.successArray.push(success);
fail && this.failArray.push(fail);
} else if (this.status === 'resolved') {
success && success(this.value);
} else {
fail && fail(this.value);
}
// 鏈式呼叫
return this;
}