promise 的基本概念 和如何解決js中的異步編程問題 對 promis 的 then all ctch 的分析 和 await async 的理解
阿新 • • 發佈:2017-08-20
委托 callback 分析 傳參 成功 visible 定時 data- 得到
* 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對象是沒有辦法確定的。
我們需要在我們業務處理中,去根據實際情況改變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.
列2 promise
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的all方法
有的時候在一個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);
})
promise 的另一種方法 await async
await async 是es7 定義的新標準
通過 async 聲明一個異步函數在該函數中
async function(){
await fn1 //這個fn1 代表一個函數
await fn2//這樣的話在fn1 執行完成之後才會執行fn2
}
promise 的基本概念 和如何解決js中的異步編程問題 對 promis 的 then all ctch 的分析 和 await async 的理解