主頁 >  其他 > 前端必備:從頭開始,搞懂Promise

前端必備:從頭開始,搞懂Promise

2020-09-10 07:35:50 其他

未來值

設想場景:你去漢堡店買漢堡,購買人數很多,無法立刻拿到漢堡,

當你付款完成后,就發出了對某個值(這里就是漢堡)的請求,此時店員就會給你一個東西代替漢堡,通常是帶有編號的收據,那么收據上的編號就是你核銷漢堡的憑證,這個編號也代表了漢堡店給你的承諾(promise),即,未來會給你一個漢堡,

此時有了收據,就可以等待(等待態)了,在等待的途中,你可以做其他的事情,

但是漢堡依舊在你的大腦中,你不會等到漢堡送來時產生“為什么給我個漢堡?”等其它疑惑,所以當漢堡送來時,你就會直接處理這個值(漢堡)——把它吃掉,

此時這個在大腦中的漢堡,你也可以理解為即將得到的漢堡,是一個“未來值”,即占住了位置,但并沒有拿到實物進行處理,反而你正在做其他事,

等待片刻后,叫到了你的號碼,你可以去領漢堡了,

此時會發生3種情況,

  1. 核對編號成功,完成交易,拿到漢堡,即,我需要的值(漢堡),已經處理好了,我拿承諾值(商家給的編號)換取這個值本身(漢堡),此時,未來值成功了(得到漢堡了),結果就是你就開始吃漢堡了,吃飽了,

  2. 核對編號成功,漢堡賣完了,值(漢堡)沒了,未來值(即將得到漢堡)失敗了(漢堡并沒得到),結果是你可能會換一個地方吃或者干別的,

  3. 商家系統故障,你的號永遠都沒被叫到,現實中有現實中的處理辦法,但在程式中,這是一種未決議狀態

從上面的例子可以看出,核對編號到拿到/未拿到漢堡到最終是吃還是沒吃的結果,這是一個完整的程序,重要的是最后的結果,是吃了還是沒吃,

這基本詮釋了使用Promise的整個流程,即Promise先決議,然后確定未來值的狀態,有成功也有失敗,成功后對應一種結果回傳,失敗后對應一種結果回傳,且只會有一種結果被回傳

未決議狀態會放在之后討論,

Promise

Promise:從語意上可以看出,它是一個承諾,承諾一段時間后給你反饋一個結果,從語法上,它是一個物件,使用new來創建,它會有三種狀態,等待pending、成功resolve、失敗rejecte,且一旦狀態確定,就無法更改,此時它成了不變值

Promise創建的任務是微任務,

未決議狀態會放在之后討論,它不是主觀觸發的一種狀態,而以上三種,是promise必備的狀態,

此時你是否想到未來值,它也有成功/失敗的狀態,

所以說:Promise會很好的展現未來值的特性,是一種封裝和組合未來值的易于復用的機制,

來看看Promise的使用語法,

let p1 = new Promise((resolve, reject) => {
      // resolve("成功");
         reject("拒絕");
        })

使用決議函式reject()表示失敗(請求拒絕),

使用決議函式resolve()表示成功,

注意,這里為了一次展示語法也為了代碼能正常執行,我將resolve(“成功”)注釋掉了,因為狀態一旦確定就無法更改,如果沒有注釋,那意思就是,先成功,后又改為失敗,這樣是不行的,只能有一個狀態存在,所以將其中一個注釋掉,

使用new來創建的promsie是標準promise,

Promise內封裝了“等待底層值的完成或拒絕”的狀態,這個狀態依賴于時間,所以是這個狀態與時間有關,而promise本身與時間無關,可以得出:Promise可以按照可預測的方式進行組合,不用擔心時序帶來的變化或底層的結果,這可以避免很多傳統異步的問題,之后我們會詳細討論,

同樣的,Promise的狀態不可更改會帶來一些好處:

使用Promise決議過的值是不變值,外部無法進行更改,那么,將這個值傳給第三方,或者多方進行觀察,它就更加安全了,因為無法被修改,

由于狀態不可更改,導致Promise產生的任務有以下特點:單一、不可逆、不可撤銷,所以,一個Promise,不能有兩種狀態賦予,

單獨的Promise展現了未來值的特性,但是,就像核銷編號完成后拿到/未拿到漢堡所產生的結果例如:吃漢堡或換家店一樣,Promise完成之后,會有一個東西來執行后面的事情,然后回傳一些東西,

使用then()方法來執行得到成功/失敗狀態后的事情,

Then()

then()方法就像是promise的配套組件,每一個promise都會有一個對應的then()

then()方法內有兩個引數,即兩個方法,分別接收resolve()和reject()傳遞過來的“信號”,收到成功狀態的信號,就傳給then()的第一個函式value,收到失敗狀態的信號,就傳給第二個引數reason,這里使用箭頭函式,你可以使用其它函式方法和命名,

    new Promise((resolve, reject) => {
            resolve("操作成功,這是業務1");
// reject("拒絕狀態,這是拒絕的業務處理 ");

    })
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> {
          console.log("成功業務處理 1");
        },
        reason => {
          console.log("拒絕的業務處理");
        }
      )

這里注釋掉了reject(),保留了resolve狀態,所以傳遞到then()時就會執行value,輸出“成功業務處理1”,

注意:promise物件有幾個引數,就要給then()幾個引數,即使是null,

一般是兩個引數,

new Promise((resolve, reject) => {
            resolve("操作成功,這是業務1");
// reject("拒絕狀態,這是拒絕的業務處理 ");

    })
.then(
      msg => {
        console.log("success:" + msg);
      },null)

這里對于reject狀態并不想處理,所以沒有處理方法,使用null,但不能沒有,會報錯,

沒有null:

Promise不僅可以用于異步問題,還能用于很多地方,這些稍后會說,現在先考慮promise最基本的方法,

鏈式Promise

在正式開始說鏈式Promise之前,我們需要搞清楚三個概念,

  1. 每個then()都是一個Promise物件,

  2. 是否在promise中return,

  3. 每個then()會優先處理離自己最近的那個promise,

先來看看第一點,

let p1 = new Promise((resolve, reject) => {
      reject("rejected");
    });
    let p2 = p1
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
        reason => console.log(reason)
      )
      console.log(p2)

其中p2就是p1的then(),將它列印出來,

可以看到,它是一個準備態的promise,

對它的操作,要么就把它當作一個準備好的微任務并放入任務串列中,要么就將它看作一個promise,為它再配套一個then(),來對這個then()產生的結果再次進行處理,

let p1 = new Promise((resolve, reject) => {
      reject("rejected");
    });
    let p2 = p1
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
        reason => console.log(reason)
      )
      .then(//.then對上一個promise進行處理,即p1.then
        a => console.log("成功"),
        b => console.log(b)
      );

第二個then()就在處理第一個then()了,可以看下運行結果,

let p1 = new Promise((resolve, reject) => {
      //resolve("fulfilled");
      reject("rejected");
    });
    let p2 = p1
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
        reason => console.log(reason)
      )
      .then(//.then對上一個promise進行處理,即p1.then
        a => console.log("成功"),
        b => console.log("失敗")
      );

注意:兩個then()之間不能插入任何的東西,

你覺得輸出的結果會是什么?

先看下瀏覽器的結果,與你的理解可能會有偏差,

你會不會覺得第二個輸出,應該是“失敗”?為什么會是成功?不是reject從上到下傳過來的嗎?

注意:第二個then()是對上一個then()進行了處理,我們對現在的p2,也就是第一個then()進行輸出,看下它的狀態,

注意:由于宏任務,微任務,同步任務的關系,我們設定一個定時器來讓輸出陳述句在微任務之后進行,才能看到微任務執行后的結果,

let p1 = new Promise((resolve, reject) => {
      //resolve("fulfilled");
      reject("rejected");
    });
    let p2 = p1
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
        reason => console.log(reason)
      )
      .then(//.then對上一個promise進行處理,即p1.then
        a => console.log("成功"),
        b => console.log(b)
      );

    setTimeout(() => {
        console.log(p2);
    });

可以看到p2的狀態是“fulfilled”,也就是成功了,所以在第二個then()中,執行了a,輸出“成功”,

原因:第二個then()處理的是第一個then(),第一個then()接收到起始promise的信號,并處理了它,它的處理程序是很成功的,所以它是成功的,它的狀態與起始promise無關,所以在接下來的第二個then()處理它時,是按照成功的狀態走的,所以執行成功,

那有沒有什么辦法,讓我們自定義傳給第二個then()的promise的狀態,

當然可以,但是并不是簡單的使用then()一直往下串,我們還是需要創建新的promise物件來重新賦予任務狀態,

此時就要討論第二點了,先看上個問題的解決辦法,

只需要在第一個then()當中新創建一個promise并且return它即可,

let p1 = new Promise((resolve, reject) => {
      resolve("fulfilled");
    }) 
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> {
          return new Promise((resolve, reject) => {//只要return了,后面的then針對的就是這個return的新promise           
              reject("處理失敗");
          })
        },
        reason => console.log(reason)
      )
      .then(//此時的then是對上面的then的處理
        value =https://blog.csdn.net/weixin_42309926/article/details/> {
          console.log("成功:" + value);
        },
        reason => console.log("error" + reason)
      );

在瀏覽器中查看結果,

起初的promise狀態為resolve,所以執行value中的函式,value將新的promise回傳,而這個新的promise的狀態是reject,所以走到第二個then()中的reason(),列印出“erro處理失敗”,

這個程序很像工廠的流水線,比如做面包,原料經過第一個機器,被做成面包胚,再經過第二個機器,被烤熟,最后的結果就是得到一個熟的面包,之前的原料和生面包胚都不復存在,沒有人會在意它們,只會在意到手的面包,

但是,注意:第一個機器需要將面包胚吐出來,才能到下一個機器那里進行加工,這就是為什么要return這個promise的原因,我們需要將當前的promise進行回傳,才能讓下一個then()處理它,

有回傳就有不回傳,不回傳會怎么樣呢?

就像原料卡在機器里不出來一樣,整個成產線都崩潰了,看看瀏覽器里的情況,

成功了是因為我們新建的promise并不影響整體流程,像之前說過的一樣,經過一輪一輪then()的處理就行,那undefined呢?

Undefined和下一行錯誤息息相關,因為我們新建了promise卻沒有給它相對應的then(),所以這個promise是不能正常創建任務的,它什么都沒有給下一個then(),但是它的狀態是resolve(),所以是“成功:undefined”,

所以說,當你需要一步一步處理你的promise時,千萬不要忘了return,

可是,并不總是需要處理標準的promise物件,就像一樣的原料,我可以讓它變成面包胚、披薩餅、或者其它的東西再傳送出去一樣,我們也可以回傳其它的型別,

例如普通的物件和類,

先來看回傳普通的物件,

let p1 = new Promise((resolve, reject) => {
      resolve("fulfilled");
    })
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> {
          return{//回傳普通的物件
            name:"Cherrie"
          }
        },
        reason => {}
      )
      .then(
        value =https://blog.csdn.net/weixin_42309926/article/details/> {
          console.log(value);
           console.dir(value);
        },
        reason => {
          console.log(reason);
        }
      );

在瀏覽器里列印它,

物件就被回傳出來了,你也可以使用它回傳其他需要的型別,回傳類,修改以上代碼即可,這里不多贅述,

在這里強調它可以回傳其它型別值的原因是,我們可以通過這個特點來回傳除標準promise以外的其它類promise型別,也就是類似標準promise的promise型別,不是我們使用的class哦,

剩下的內容會盡快更新,每日更新或每兩日更新,敬請期待~~

omise((resolve, reject) => {

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/1330.html

標籤:其他

上一篇:JWT的基本介紹

下一篇:IDEA Plugins中 搜索插件時找不到任何插件資訊

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more