ES6中Promise用法詳解
Promise
promise就是個建構函式,引數為一個函式
建構函式一般使用其例項進行操作,如何得到一個建構函式的例項呢?
1、new Promise(引數:函式);
2、引數為一個函式,這個函式同樣也有兩個引數 resolve reject,這兩個引數也是函式
resolve執行後返回promise的成功狀態,
reject執行後返回promise的錯誤狀態
基本使用形式:
var p = new Promise(function(resolve,reject){
console.log("結果");
resolve("結果")
})
//以上程式碼將一段同步程式碼封裝成了一個promise例項,promise例項有兩個三個狀態
//peding 正在請求
//resolved 成功
//rejected 失敗
//這個例項內部呼叫resolve,返回成功狀態,並將結果通過resolve傳遞。
//傳遞出來的結果如何使用呢?
//下面的程式碼,通過呼叫promise例項上面的then方法來獲得resolve傳遞的資料。
p.then(function(data){
console.log(data)
})
從上面的程式碼可以總結一下promise的特點:
- 只要一 new ,promise就執行了,並且得到一個promis例項
- promise例項內部結果通過resolve進行傳遞
- 通過呼叫promise例項的then方法獲取resolve傳遞的結果;
一般用promise幹什麼呢?
包裝非同步執行程式碼,將其轉化為同步執行的樣式,
比方傳送一個ajax常規方法:
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
console.log(data);
})
轉化為Promise如下:
let p = new Promise((resolve,reject)=>{
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
resolve(data)
})
});
p.then((data)=>{
//執行程式碼邏輯
console.log(data)
})
在實際開發中使用
但是一般在開發中一般不會把new Promise直接暴露在外面,而是封裝成一個函式,上面程式碼修改如下:
function fn(){
let p = new Promise((resolve,reject)=>{
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
resolve(data)
})
});
return p
}
fn().then((data)=>{
console.log(data)
})
如何學習promise???
根據作用需求/場景來學習,需求如下:
比方一個頁面載入進來,需要傳送5個ajax請求,並需要把結果統一經行處理:
- 首先大家按照大家已有的知識點來思考一下如何解決呢?
程式碼如下:
$(function(){
var arr = []
$.get("https://cnodejs.org/api/v1/topics?tab=ask",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=job",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=good",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
arr.push(data);
console.log(arr)
})
})
})
})
})
簡稱 回撥地獄
缺點耗費時間,看圖說話:
之前我們可能會用解決方法。
(function () {
var count = 0;
var arr = [];
function handle() {
if (count === 4) {
console.log(arr);
}
}
$.get("https://cnodejs.org/api/v1/topics?tab=good",function(data){
arr.push(data);
count++;
handle()
})
$.get("https://cnodejs.org/api/v1/topics?tab=job",function(data){
arr.push(data);
count++;
handle()
})
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
arr.push(data);
count++;
handle()
});
$.get("https://cnodejs.org/api/v1/topics?tab=ask",function(data){
arr.push(data);
count++;
handle()
});
})();
但是這種依然有個缺點,得寫監控函式,每次回撥都會呼叫監控函式,耗費效能,還有其他方法嗎?
檢視network 中的waterfall;
Promise 來了,用promise怎麼實現呢?
程式碼如下:
$(function(){
// 封裝一個promise;將url提取出來;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
Promise.all([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p("https://cnodejs.org/api/v1/topics?tab=share"),
p("https://cnodejs.org/api/v1/topics?tab=ask"),
p("https://cnodejs.org/api/v1/topics?tab=job"),
]).then(function(result){
console.log(result);
})
})
waterfall圖如下:
有的時候有這樣的需求,後面的ajax請求依賴前面的ajax請求必須按照順序調動如何實現呢?
前面的回撥是一種解決方案,但是想避免回撥地獄的寫法用promise實現順序呼叫呢?
$(function(){
// 封裝一個promise;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
var arr = []
p("https://cnodejs.org/api/v1/topics?tab=ask")
.then(function(data){
arr.push(data);
return p("https://cnodejs.org/api/v1/topics?tab=share")
}).then(function(data){
arr.push(data);
return p("https://cnodejs.org/api/v1/topics?tab=ask")
}).then(function(data){
arr.push(data);
return p("https://cnodejs.org/api/v1/topics?tab=good")
}).then(function(data){
arr.push(data);
console.log(arr);
})
})
waterfall執行圖:
再看一個應用場景:
請求多個資源,哪個介面先返回,就處理哪個介面的資訊:
一般應用的比較多的是分散式應用,舉例子說明,
四臺 伺服器分別位於 北京 上海 南京 鄭州:畫圖說明
這應用到一個race介面,將4.html的js程式碼改成如下:
$(function(){
// 封裝一個promise;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
Promise.race([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p("https://cnodejs.org/api/v1/topics?tab=share"),
p("https://cnodejs.org/api/v1/topics?tab=ask"),
p("https://cnodejs.org/api/v1/topics?tab=job"),
]).then(function(result){
console.log(result);
})
})
執行看結果,誰最先返回就列印誰的資料:
再來看一個需求,傳送一個請求,請求超時後返回特定資訊如何實現:
jquery版本:
$.ajax({
url:'https://cnodejs.org/api/v1/topics?tab=good', //請求的URL
timeout : 1000, //超時時間設定,單位毫秒
type : 'get', //請求方式,get或post
data :{}, //請求所傳引數,json格式
dataType:'json',//返回的資料格式
success:function(data){ //請求成功的回撥函式
alert("成功");
},
error:function(){
console.log("超時了")
}
});
//設定timeout的時間,超時後觸發error函式。
Promise版本如何實現呢?
- 封裝兩個Promise
- 一個promise裡面封裝ajax請求
- 一個Promise封裝定時器
- 呼叫Promise類的race方法
- 鏈式呼叫then方法獲得執行結果。
注意:Promise.race的引數為一個陣列,陣列每一項都是promise例項物件。
Promise.race的返回結果為一個Prmise例項,只不過這個例項只能是最先執行resolve的那個promise。
$(function(){
// 封裝一個promise;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
var p2 = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve('請求超時了')
},100)
})
}
Promise.race([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p2()
]).then(function(result){
console.log(result);
})
})
promise捕獲錯誤的使用.
如何捕獲promise的錯誤呢?在promise的呼叫鏈的最後呼叫catch函式,一旦promise呼叫鏈中有reject執行,promise就會終止執行直接進入catch函式,否則catch不會執行。
$(function(){
// 封裝一個promise;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
// P2的另一種形態:
// 如果是reject會直接跳到catch裡面去,如果是resolve,會接著執行,不會跳躍
var p2 = function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
reject("err");
},100)
})
}
Promise.race([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p2()
]).then(function(result){
console.log(result);
}).then(function(){
console.log("我執行了")
}).catch(function(data){
console.log(data);
})
})
javascript的巨集任務和微任務
看一道面試題:
setTimeout(
function(){
console.log('1')
}
);
new Promise(
function(resolve, reject){
resolve()
console.log('2');
}).then(function(){
console.log('3')
});
console.log('4');
請問這段程式碼的執行結果是什麼?
回憶javascript的非同步機制,如圖:
這張圖不是很完整,在javascript中分為巨集任務(macrotask)和微任務(micro-task);
巨集任務(macrotask)包括 cript(整體程式碼), setTimeout, setInterval, setImmediate, I/O, UI rendering
micro-task: process.nextTick, Promises(這裡指瀏覽器實現的原生 Promise)
;
相關文章
- ES6 Promise 用法講解Promise
- ES6 Promise 用法講解(轉)Promise
- ES6中的Promise和Generator詳解Promise
- Promise用法詳解(一)Promise
- ES6新特性Promise詳解Promise
- ES6 Promise用法小結Promise
- es6中的promise解讀Promise
- ES6 - 整理一下Promise 的用法Promise
- ES6中的PromisePromise
- ES6中的Promise物件Promise物件
- [Javascript] Promise ES6 詳細介紹JavaScriptPromise
- 詳解promisePromise
- promise詳解Promise
- STL中set用法詳解
- STL中map用法詳解
- JavaScript Promise 詳解JavaScriptPromise
- java中printf中用法詳解Java
- Java中jar命令用法詳解JavaJAR
- ES6 中 Promise物件使用學習Promise物件
- ES6 - PromisePromise
- Promise ES6Promise
- es6—PromisePromise
- TS 版 Promise 詳解Promise
- MySQL中BETWEEN子句的用法詳解MySql
- 詳解MySQL中WHERE子句的用法MySql
- Java 中 this 和 super 的用法詳解Java
- C++ 中 this 指標的用法詳解C++指標
- PHP中return用法詳細解讀PHP
- php中mysql操作buffer用法詳解PHPMySql
- Android中的ANR用法詳解Android
- Android中Context用法詳解AndroidContext
- insert 中append 用法詳解APP
- 關於 ES6 中 Promise 的面試題Promise面試題
- Promise基本用法Promise
- Promise 用法解析Promise
- promise用法解析Promise
- Promise的用法Promise
- Javascript Promise用法JavaScriptPromise