* promise承諾 * 解決js中異步編程的問題 * * 異步-同步 * 阻塞-無阻塞 * * 同步和異步的區別? 異步;同步 指的是被請求者 解析:被請求者(該事情的處理者)在處理完事情的時候的通知機制。 異步:當事情處理完成後被請求者會發信息通知請求者該事情處理完成。在這期間被請求者能夠選擇是繼續等待命令請求完成仍是去作其餘事等待被請求者返回。 同步:當事情處理完成後被請求者不會告知請求者,等到請求者發來詢問是纔會告知 阻塞;非阻塞 指的是請求者 阻塞:針對請求者來講的,委託其餘人處理一些事情的時候,被請求者是等待請求處理完成仍是繼續向下執行其餘任務。阻塞就是等待事情完成才繼續執行 非阻塞:針對請求者來講,請求者委託被請求者處理一些事情時不等被請求者答案先去作其餘事,而且每隔一段時間詢問被請求者該事件是否完成。 js採用的是異步非阻塞模式。 promise 是一個構造函數(在何時要用promise當咱們進行一些操做須要同步進行時) 經過new promise進行調用 Promise: * 構造函數 * new Promise(callback) * callback: 要異步處理的任務 經過Promise構造函數獲得一個Promise對象,咱們傳入的callback將會被Promise對象所執行 * Promise會維護一個任務狀態,這個狀態是一個Promise內部的屬性 * [[PromiseStatus]] * 該屬性一共有三個值 * 1. pending : 正在處理,Promise對象一旦被建立就會更改成該狀態,他是默認值 * 2. resolved : 處理完成 * 3. rejected : 處理失敗 * resolved,rejected這兩個狀態是須要靠咱們手動去維護的。由於異步任務的結果是成功仍是失敗,是由咱們的具體業務所決定的,Promise對象是沒有辦法肯定的。
web
咱們須要在咱們業務處理中,去根據實際狀況改變Promise對象的狀態 * 改變Promise狀態 * 當咱們把一個callback函數傳遞給Promise對象的時候,Promise對象會去執行該callback函數,同時,還會傳遞兩個參數給這個callback,因此,咱們能夠在callback函數接收這兩個參數 * 這兩個參數都是一個函數 * resolve * 當咱們調用該函數的時候,會把當前的Promise對象的狀態改爲resolved * reject * 當咱們調用該函數的時候,會把當前的Promise對象的狀態改爲rejected * * Promise對象還有一個方法:then * 該方法接收兩個參數,這兩個參數都是callback函數,這兩個callback不會當即執行,當Promise的狀態一旦發生改變就會執行then方法中傳入的函數,有點相似事件綁定 * 當Promise狀態變成resolved,那麼執行then的第一個參數callback * 當Promise狀態變成rejected,那麼執行then的第二個參數callback 舉列:如今咱們有一個延時定時器setTimeout 以下 var a=10; setTimeout(()=>{ a+=10; },1000); console.log(a);//此時a打印出來爲10 由於在js爲異步非阻塞的語言 在延時定時器中的函數尚未執行的時候下面的console.log就已經執行完畢因此打印出來爲10 。 那麼咱們想獲得延時定時器處理後的值能夠這麼作。 var a=10; var p1=new Promise((resolve,reject)=>{ setTimeout(()=>{ a+=10; resolve(err)//處理完成 },1000);//只有當處理完成以後纔會執行then中的函數 此時resolve()中的東西爲then的傳參。 }) p1.then(()=>{ console.log(a) }); 此時打印出來的就是20.
then方法如何傳遞數據 * 咱們能夠經過resolve,reject方法來傳遞數據 * 咱們只要在調用上面兩個函數的時候,把須要傳遞給後續的then方法的數據做爲其參數就能夠 * catch也是相似catch方法就是捕獲在promise的then中又傳遞了promise這樣多個嵌套的話 拿 then 的 方法來監聽太過繁瑣 catch 監聽 主要有一個執行錯誤就會被catch捕獲從而執行catch中的函數 * */ new Promise((resolve, reject) => { let b = 10; setTimeout(() => { b += 10; resolve(b); // reject('第一個任務出錯了'); }, 1000); }).then(function(b) { console.log(b); return new Promise((resolve, reject) => { setTimeout(() => { b *= 2; resolve(b); // reject('第二個任務出錯了'); }, 1000); }); }).then(function(b) { console.log(b); return new Promise((resolve, reject) => { setTimeout(() => { b *= b; resolve(b); reject('第三個任務出錯了'); }, 1000); }); }).then(function(b) { console.log(b); }).catch(function(err) { console.log(err); });
有的時候在一個Promise任務中須要處理多個異步任務,那這多個異步的任務是同時執行的,可是執行時間有是不肯定的。後續的任務須要這幾個異步任務所有完成之後再執行,那麼就須要用到Promise中提供的all方法來實現
var p1 = new Promise((resolve, reject) => { let a = 1; setTimeout(() => { a++;
// reject('one'); resolve(a); }, Math.random() * 1000); });編程
var p2 = new Promise((resolve, reject) => { let b = 2; setTimeout(() => { b++; resolve(b); }, Math.random() * 1000); }); /* * 把兩個不一樣的異步任務分別包裝在一個Promise對象中,而後調用Promise對象靜態方法all,把上面多個不一樣異步Promise做爲數組傳遞給all方法的參數 * 這個時候Promise.all方法中會維護一個狀態,這個狀態是根據傳入的多個異步任務的狀態共同決定的 * 當多個異步任務的狀態都變成了resolved,那麼all的狀態纔是resolved,可是隻要有一個異步任務的狀態變成了rejected,那麼all的狀態就會變成rejected * */ p1 p2 是兩個promise 在下面的方法中只有當p1 p2 都爲resolved的時候纔會執行下面的函數方法 Promise.all([p1, p2]).then(([a, b]) => { console.log(a, b); }).catch((err) => { console.log(err); })
await async 是es7 定義的新標準 經過 async 聲明一個異步函數在該函數中 async function(){ await fn1 //這個fn1 表明一個函數 await fn2//這樣的話在fn1 執行完成以後纔會執行fn2 }