淺析Promise的介紹及基本用法
Promise是ES6引入的異步編程的新解決方案。語法止Promise是-一個構(gòu)造函數(shù),
用來封裝異步操作并可以獲取其成功或失敗的結(jié)果。
- Promise 構(gòu)造函數(shù): Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
Promise的基本使用
實例化Promise
new Promise()
在實例化的時候接受一個參數(shù), 這個參數(shù)是一個函數(shù)。
這個函數(shù)有兩個形參,resolve 和 reject
var promise = new Promise((resolve,reject) => { // 里面用于處理異步操作 })
我們在這里使用定時器來模擬異步操作
promise有三種狀態(tài),分別是:進(jìn)行中、成功、失敗。
var promise = new Promise((resolve,reject) => { // 這是一個異步操作 setTimeout(() => { // 這里模擬獲取數(shù)據(jù) var data = '獲取的數(shù)據(jù)' // 在得到數(shù)據(jù)之后我們可以調(diào)用resolve和reject方法來改變promise對象的狀態(tài) resolve(data) // resolve可以將promise對象的狀態(tài)改為成功,reject()可以promise將對象狀態(tài)改為失敗 }, 1000); })
promise的then方法
當(dāng)promise對象的狀態(tài)為成功或者失敗時可以調(diào)用then方法
then方法接受兩個參數(shù),而且兩個參數(shù)都是函數(shù)類型的值
promise對象的狀態(tài)為成功時,會調(diào)用then方法的第一個參數(shù)
也是就說promise對象的狀態(tài)為失敗時,會調(diào)用then方法的第二個參數(shù)
第二個參數(shù)時可選的,如果不需要捕獲失敗可以省略
參數(shù)分別有一個形參,成功的函數(shù)叫value, 失敗的err
promise.then(value => { // 當(dāng)異步函數(shù)里面調(diào)用了resolve(data),也是就說promise對象的狀態(tài)為成功時,會調(diào)用then方法的第一個參數(shù) console.log(value); // 'hello world' value就是resolve()方法傳遞過來的數(shù)據(jù) }, err => { // 當(dāng)異步函數(shù)里面調(diào)用了reject(data),也是就說promise對象的狀態(tài)為失敗時,會調(diào)用then方法的第二個參數(shù) console.log(err); // err就是reject()方法傳遞過來的數(shù)據(jù) })
調(diào)用then方法then方法的返回結(jié)果是Promise 對象,對象狀態(tài)由回調(diào)函數(shù)的執(zhí)行結(jié)果決定
如果回調(diào)函數(shù)中返回的結(jié)果是非promise類型的屬性,狀態(tài)為成功,返回值為對象的成功的值
let data = promise.then((val) => { // console.log(val.result); // 返回非Promise的情況 // return val.result // 返回Promise的情況 return new Promise( (resolve, reject) => { // resolve('ok') reject('err') }) }, err => { console.log(err); }) // 返回非Promise的情況 狀態(tài)為成功,返回值為對象的成功的值 // 返回結(jié)果是Promise 對象,對象狀態(tài)由回調(diào)函數(shù)的執(zhí)行結(jié)果決定 // 拋出錯誤,狀態(tài)為失敗 console.log(data);
所以then可以鏈?zhǔn)秸{(diào)用使用方法可參見下面promise應(yīng)用示例。
promise的catch方法
promise的catch方法是then(null, rejection)的別名,用于指定發(fā)生錯誤時的回調(diào)
Promise對象的狀態(tài)為resolve,就會調(diào)用then方法的指定回調(diào)函數(shù)
const promise = new Promise((resolve, reject) => { resolve('ok') }) promise.then(val => { console.log(val); // ok }).catch(err => { console.log(err); })
如果promise的狀態(tài)為rejected就會調(diào)用catch方法的回調(diào)函數(shù)來處理這個問題。
const promise = new Promise((resolve, reject) => { reject('err') }) promise.then(val => { console.log(val); }).catch(err => { console.log(err); // err })
如果then方法在運(yùn)行中出現(xiàn)錯誤也會被catch方法捕獲
const promise = new Promise((resolve, reject) => { resolve('err') }) promise.then(val => { console.log('ok'); // ok throw '出錯了!!' // then里面拋出的錯誤會繼續(xù)被catch捕獲 }).catch(err => { console.log(err); // 出錯了!! })
promise對象的錯誤具有冒泡的性質(zhì),會一直向后傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch捕獲。
const promise = new Promise((resolve, reject) => { resolve('ok') }) promise.then(val => { return new Promise((resolve, reject) => { reject('err') }) }) .then(val => { return new Promise((resolve, reject) => { reject('err') }) }) .catch(err => { // 以上產(chǎn)生的錯誤都可以被catch捕獲到 console.log(err); // err })
一般來說,不要在then方法中定義rejected狀態(tài)回調(diào)函數(shù)(即then的第二個參數(shù)),而應(yīng)總是使用catch方法。
promise應(yīng)用
promise讀取文件,多個文件連續(xù)調(diào)用
在這個例子中我們用到了Node.js的文件模塊
// 讀取文件信息 const fs = require('fs')
在下面代碼中我們使用了promise包裝了異步函數(shù)
我們先來看看正常的文件讀取操作
// 讀取文件信息 const fs = require('fs') // 如果讀取失敗err就是一個錯誤對象,讀取成功data就是數(shù)據(jù) fs.readFile('./01.txt', (err, data) => { // 判斷是否出現(xiàn)錯誤,如果讀取錯誤就打印錯誤對象。 if (err) { console.log(err); return } console.log(data.toString()); })
我們?nèi)绻朐谧x取成功之后繼續(xù)讀取文件,就需要在回調(diào)函數(shù)中繼續(xù)使用fs.readFile...去讀取文件,嵌套層次一多,這樣一來就會形成回調(diào)地獄。
接下來我們使用Promise的方式來讀取文件
// 讀取文件信息 const fs = require('fs') const promise = new Promise((resolve, reject) => { fs.readFile('./01.txt', (err, data) => { if (err) return reject(err) resolve(data) }) }) promise.then(val => { console.log(val.toString()); // 返回一個Promise對象 return new Promise((resolve, reject) => { fs.readFile('./02.txt', (err, data) => { if (err) return reject(err) resolve(data) }) }) }, err => { console.log(err); }) // 上一個then里面返回的是一個promise對象,我們可以繼續(xù).then .then(val => { console.log(val.toString()); return new Promise((resolve, reject) => { fs.readFile('./03.txt', (err, data) => { if (err) return reject(err) resolve(data) }) }) }, err => { console.log(err); }) .then(val => { console.log(val.toString()); }, err => { console.log(err); })
promise封裝ajax請求
封裝了ajax請求,使用then獲取結(jié)果,讓代碼看起來更加簡潔,解決了回調(diào)地獄的問題
const promise = new Promise((resolve, reject) => { // 創(chuàng)建對象 const xhr = new XMLHttpRequest() // 初始化 xhr.open("GET", 'https://api.apiopen.top/getSongPoetry?page=1&count=20') // 發(fā)送 xhr.send() // 綁定事件處理響應(yīng)結(jié)果 xhr.onreadystatechange = function () { // 判斷 // 進(jìn)入最后一個階段,所有的響應(yīng)體都回來了 if (xhr.readyState === 4) { // 判斷響應(yīng)碼 if (xhr.status >= 200 && xhr.status < 300) { // 表示成功 // console.log(JSON.parse(xhr.response)); resolve(JSON.parse(xhr.response)) } else { reject(xhr.status) } } } }) // 指定回調(diào) promise.then((val) => { console.log(val); }, err => { console.log(err); })
到此這篇關(guān)于淺析Promise的介紹及基本用法的文章就介紹到這了,更多相關(guān)Promise使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript下一版本標(biāo)準(zhǔn)ES6的Set集合使用詳解
ES6:全稱ECMAScript 6.0,是JavaScript語言的國際標(biāo)準(zhǔn),JavaScript是ECMAScript的實現(xiàn)。今天我們就來學(xué)習(xí)一下ES6的Set集合的使用2023-02-02JavaScript數(shù)據(jù)結(jié)構(gòu)之棧實例用法
在本篇文章里小編給大家分享了關(guān)于JavaScript數(shù)據(jù)結(jié)構(gòu)之棧實例用法內(nèi)容,有興趣的朋友們學(xué)習(xí)下。2019-01-01javascript 循環(huán)語句 while、do-while、for-in、for用法區(qū)別
本文章介紹了在學(xué)習(xí)javascript中的循環(huán)語句的用法,包while、do-while、for-in、for它們之間的區(qū)別,也是常用的循環(huán)語句了,有需要的朋友可以了解一下2012-03-03利用types增強(qiáng)vscode中js代碼提示功能詳解
這篇文章主要給大家介紹了如何增強(qiáng)vscode中js代碼提示功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-07-07JavaScript defineProperty如何實現(xiàn)屬性劫持
雙向數(shù)據(jù)綁定的核心方法,主要是做數(shù)據(jù)劫持操作(監(jiān)控數(shù)據(jù)變化),下面這篇文章主要給大家介紹了關(guān)于JavaScript defineProperty如何實現(xiàn)屬性劫持的相關(guān)資料,需要的朋友可以參考下2021-07-07一文帶你搞懂JavaScript中的進(jìn)制與進(jìn)制轉(zhuǎn)換
JavaScript 中提供的進(jìn)制表示方法有四種:十進(jìn)制、二進(jìn)制、十六進(jìn)制、八進(jìn)制。本文主要講介紹一下JS中這些進(jìn)制的互相轉(zhuǎn)換,感興趣的可以了解一下2023-02-02