自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

寫給 Java 程序員的前端 Promise 教程

開發(fā) 前端
小伙伴們知道,松哥最近在錄 TienChin 項(xiàng)目,用的 RuoYi-Vue 腳手架,前端關(guān)于網(wǎng)絡(luò)請求的地方,很多都涉及到了 Promise,為了讓小伙伴們能更好的理解前端代碼,咱們抽空整一篇文章和大家聊聊整個(gè) Promise。

1. 為什么需要 Promise

假設(shè)我現(xiàn)在有這樣一個(gè)需求,用戶先去登錄,登錄成功之后,再去服務(wù)端獲取用戶信息,獲取到用戶信息之后再去服務(wù)端獲取前端的動態(tài)菜單。一般我們的 Ajax 請求都是異步形式,為了確保上一步操作成功再執(zhí)行下一個(gè)請求,所以最終發(fā)出的請求偽代碼類似下面這樣:

$.ajax({    url:'/login',    data:loginForm,    success: function (data) {        //登錄成功        $.ajax({            url:'/getInfo',            success: function (userInfo) {                //獲取用戶信息成功                $.ajax({                    url: '/getMenus',                    success: function (menus) {                        //獲取菜單成功                    }                })            }        })    }})

為了確保一個(gè)異步任務(wù)執(zhí)行完成后,再執(zhí)行下一個(gè)異步任務(wù),我們不得不在回調(diào)函數(shù)中不停的寫下去,上面我舉的例子是三個(gè)請求嵌套,實(shí)際上可能會更多。。。這就是前端所謂的回調(diào)地獄。而 Promise 就是來解決回調(diào)地獄的。

2. Promise

Promise 從字面上理解,就是承諾,承諾將來在某一個(gè)時(shí)間會做某一件事。通過 Promise 我們可以將異步任務(wù)執(zhí)行的代碼和處理的代碼完全分離開。

還是第一小節(jié)這個(gè)例子,如果我們用 Promise 寫,那么方式如下:

function login(resolve, reject) {    setTimeout(() => {        let number = Math.random();        if (number > 0.5) {            resolve("login success")        } else {            reject("login failed")        }    }, 2000);}function getInfo(resolve, reject) {    setTimeout(() => {        let number = Math.random();        if (number > 0.5) {            resolve("getInfo success")        } else {            reject("getInfo failed")        }    }, 2000);}function getMenus(resolve, reject) {    setTimeout(() => {        let number = Math.random();        if (number > 0.5) {            resolve("getMenus success")        } else {            reject("getMenus failed")        }    }, 2000);}new Promise(login).then(data => {    console.log("login:", data);    return new Promise(getInfo);}).then(data => {    console.log("getInfo:", data);    return new Promise(getMenus);}).then(data => {    console.log("getMenus", data);}).catch(err => {    console.log("err:", err);})

我們在 Promise 中寫異步任務(wù)執(zhí)行的代碼,在上面的案例中,松哥通過 setTImeout 方法模擬了一個(gè)耗時(shí)操作,異步任務(wù)執(zhí)行完畢后,我們調(diào)用 resolve 方法返回調(diào)用的結(jié)果(會進(jìn)入到下一步的 then 中),也可以調(diào)用 reject 方法表示調(diào)用失?。〞M(jìn)入到 catch 中)。

3. then

then 中的返回值可以分為三種情況。

3.1 正常 return

then 中方法的參數(shù),是上一個(gè) Promise 對象 resolve 的值,一個(gè) Promise 對象可以有多個(gè) then,例如上面案例的登錄功能,我們可以一直 then 下去:

function login(resolve, reject) {    setTimeout(() => {        let number = Math.random();        if (number > 0.5) {            resolve("login success")        } else {            reject("login failed")        }    }, 2000);}new Promise(login).then(data => {    console.log("then1:", data);    return data;}).then(data => {    console.log("then2:", data);    return data;}).then(data => {    console.log("then3:", data);}).catch(err => {    console.log("err:", err);})

這樣可以一直返回,這有點(diǎn)像我們 Java 中的流式編程。

3.2 拋出異常

在 then 中,我們可以對返回結(jié)果進(jìn)行判斷,不滿足條件也可以直接拋出異常,這樣就會進(jìn)入到最近的 catch 代碼塊中。如下案例:

function login(resolve, reject) {    setTimeout(() => {        let number = Math.random();        if (number > 0.5) {            resolve("login success")        } else {            reject("login failed")        }    }, 2000);}new Promise(login).then(data => {    console.log("then1:", data);    throw new Error("出錯(cuò)啦");}).then(data => {    console.log("then2:", data);    return data;}).then(data => {    console.log("then3:", data);}).catch(err => {    console.log("err:", err);})

像上面這段代碼,如果進(jìn)入到第一個(gè) then 中,第一個(gè) then 直接拋出異常,這樣直接就進(jìn)入到 catch 中了,后面的 then 就都不會執(zhí)行了。

3.3 返回 Promise

第三種情況就是 then 中也可以返回一個(gè) Promise 對象,這個(gè)就如同我們第二小節(jié)的案例,我這里就不再贅述了。

就說一句,如果 then 中返回的是一個(gè) Promise 對象,那么接下來的 then 其實(shí)是這個(gè) Promise 對象的 then,而不是一開始的 Promise 的 then 了。例如如下偽代碼:

A.then((data)=>{return B}).then(xxx)

假設(shè) A 和 B 都是 Promise 對象,那么第二個(gè) then 方法是 B 的 then。

好啦,這就是 then 中的三種返回值情況。

4. catch

catch 主要是用來處理異常的情況,兩種情況下會進(jìn)入到 catch 中:

  • Promise 執(zhí)行的時(shí)候通過 reject 返回?cái)?shù)據(jù)。
  • then 中拋出 Error

出了問題,就由最近的 catch 來處理。

5. finally

最后還有一個(gè) finally 用來兜底,這一套下來感覺有點(diǎn)像我們 Java 中的 try-catch-finally,也就是前面無論如何,最終 finally 中的代碼都會執(zhí)行。不過不同于 Java 中的 finally,Promise 中的 finally 在最終執(zhí)行完畢后,還可以繼續(xù) then。。。前端的蜜汁操作。

6. 其他方法

最后,我們再來看看 Promise 中的其他靜態(tài)方法。

6.1 Promise.all()

Promise.all() 方法可以接收多個(gè) Promise 對象,并且只返回一個(gè) Promise 實(shí)例,這個(gè)方法會等所有輸入的 Promise 對象的 resolve 方法都返回的時(shí)候,或者所有輸入的 Promise 對象中有一個(gè) reject 的時(shí)候,這個(gè) all 就會執(zhí)行結(jié)束,來看如下一個(gè)案例:

const promise1 = Promise.resolve(3);const promise2 = 42;const promise3 = new Promise((resolve, reject) => {    setTimeout(resolve, 3000, 'foo');});Promise.all([promise1, promise2, promise3]).then((values) => {    console.log(values);}).catch(err=>{    console.log("err", err);})

當(dāng) promise1、promise2 以及 promise3 都執(zhí)行了 resolve 的時(shí)候,就會進(jìn)入到 then 中,這三個(gè)中有任意一個(gè)執(zhí)行了 reject 就會進(jìn)入到 catch 中。

6.2 Promise.race()

Promise.race() 方法可以接收多個(gè) Promise 對象,一旦迭代器中的某個(gè) Promise resolve 或 reject,返回的 Promise 就會 resolve 或 reject。

和 all 方法的區(qū)別在于,race 方法是誰執(zhí)行的快,就用誰的結(jié)果。我們來看如下一段代碼:

const promise1 = new Promise((resolve, reject) => {    setTimeout(resolve, 500, 'one');});const promise2 = new Promise((resolve, reject) => {    setTimeout(reject, 600, 'two');});Promise.race([promise1, promise2]).then((value) => {    console.log(value);});

promise1 執(zhí)行時(shí)間短,promise2 執(zhí)行時(shí)間長,所以最終結(jié)果就是 promise1 的結(jié)果。

6.3 Promise.reject()

Promise.reject() 方法返回一個(gè)帶有 reject 原因的 Promise 對象。來看如下一段代碼:

function resolved(result) {    console.log('Resolved');}function rejected(result) {    console.error(result);}Promise.reject("error").then(resolved).catch(rejected);

這個(gè)執(zhí)行的時(shí)候就會進(jìn)入到 catch 中。

6.4 Promise.resolve()

Promise.resolve(value) 方法返回一個(gè)以給定值解析后的 Promise 對象。

const promise1 = Promise.resolve(3);promise1.then(data=>{    console.log("data", data);},err=>{    console.log("err", err);})

這個(gè)用法比較簡單,沒啥好說的。?

責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2022-08-08 10:45:49

PromiseJava腳手架

2019-01-04 12:46:03

程序員技能溝通

2010-12-30 10:04:49

Linux入門

2016-01-05 10:30:59

后端程序員緩存原理

2019-09-27 14:33:34

2015-08-14 13:51:22

程序員

2015-06-11 13:12:56

2020-07-13 08:08:05

程序員軟考原理

2012-11-08 09:49:30

C++Java程序員

2014-08-13 10:38:01

2015-11-03 15:17:28

前端程序員特色

2015-12-04 09:33:15

程序員前端演進(jìn)史

2012-11-02 13:47:31

Java程序員編程

2009-02-19 11:02:17

2013-08-20 09:33:59

程序員

2015-11-04 10:30:06

前端文藝范程序員

2011-05-13 14:34:02

程序員

2014-07-29 10:30:16

JavaJava程序員

2018-11-01 15:20:17

前端程序員編程語言

2024-05-06 00:00:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號