好程式設計師web前端教程分享怎麼用promise解決回撥和非同步

好程式設計師IT發表於2019-12-06

好程式設計師web 前端教程分享 怎麼用promise 解決回撥和非同步

首先讓我們看看下面這題輸出什麼?

```

setTimeout(function() {

      console.log(1);

},1000)

console.log(2);

```

我們得到的結果是: 先輸出 2, 後輸出 1; 這是什麼原因呢?大家應該都知道定時器是非同步的 ; 所以先先輸出 2;

那麼我們的需求來了, 怎麼先輸出 1, 然後輸出 2 呢?

```

function foo(callback) {

setTimeout(function() {

console.log(1);

callback();

},1000)

}

foo(function() {

       console.log(2);

})

```

現在我們看看列印的結果吧, 果然先輸出的 1, 然後輸出 2 ; 這個是透過回撥函式解決的 ;

現在我麼你的需求變了, 我們每隔 1 秒後做一次輸出 ;

```

function foo(callback) {

setTimeout(function() {

console.log('1 秒後輸出 ');

callback()

}, 1000)

}

foo(function() {

console.log(' 第一次輸出 ');

foo(function() {

console.log(' 第二次輸出 ');

foo(function() {

console.log(' 第二次輸出 ');

})

})

})

```

這樣是不是解決我們的問題了呢?

> 是的 , 但是如果我們多來幾次 , 大家會不會發現回撥的太多了嗎?這就是大家所說的毀掉地獄 ;

 

### 所以 ES6 給我們提供了一個解決毀掉地獄的方法 :promise;

**promise 是一種用非同步的方式處理值的方法 ,promise 是一個物件 , 解決層層巢狀問題 **

####promise 物件的狀態 :

> 進行中 : pending

成功: resovled

失敗: rejected

 

**promise 物件的方法 :**

>then() 成功後執行 ; 如果有兩個引數 : 第一個引數成功後執行 , 第二個引數失敗後執行 ;

catch() 失敗後執行 ;

promise all([]).then() 都成功後執行圖 then 的第一個方法 ;

promise.race[(p1,p2,p3,---)] 只要有一個率先改變狀態 ,promise 就會執行對應的狀態

```

var promise = new Promise(function (resolved, rejected) {

resolved('ok');

rejected('no');

// 如果成功和失敗同時寫 , 執行先寫的 ;( 特點狀態一旦改變,就不可逆了 )

});

promise.then(function(msg) {

console.log('ok ' + msg);

},function (msg) {

console.log('no ' + msg);

});

```

列印結果是: ok: ok

現在我們做一個練習: 使用 promise 載入一張圖片 ; 載入成功就將圖片載入到 body , 如果載入失敗 , 提示失敗 ;

```

var promise = new Promise(function (resolved, rejected) {

var img = document.createElement('img');

img.src = './img/1.png';

img.() {

resolved(img)   // 如果載入成功就返回 resolved(

}

img.() {

rejected(' 失敗 ')    // 如果載入成功就返回 rejected(

}

})

promise.then(function (msg) {

document.body.appendChild(msg)

},function (msg) {

alert(msg)

})

```

怎麼樣大家是不是對promise 有了瞭解?

那麼怎麼用promise 解決非同步的問題呢?我們還是每隔 1 秒後做一次輸出 ;

```function fn() {

var promise = new Promise(function(resolved, rejected) {

setTimeout(function() {

console.log(' 每隔一秒 ');

resolved()

}, 1000)

});

return promise;

}

fn().then(function() {

console.log(' 第一次輸出 ');

return fn()

}).then(function() {

console.log(' 第二次輸出 ');

return fn()

}).then(function () {

console.log(' 第三次輸出 ');

})

```

Promise 如何解決 ajax 回撥的問題呢?我們們繼續往下看 .

```

function ajaxPromise(url) {

var promise = new Promise(function(resolved, rejected) {

var xhr = new XMLHttpRequest();

xhr.open('get', url);

xhr.send();

xhr.{

if (xhr.readyState === 4 && xhr.status === 200) {

resolved( xhr.responseText);   // 告訴 promise 成功了

}

}

setTimeout(function () {//5 秒後請求不到

rejected('error')  // 告訴 promise 失敗了

},5000)

})

return promise;

}

document.() {

var pro = ajaxPromise('data.json');

pro.then(function (msg) {

alert(msg)   // 如果路徑對了 , 我們得到了資料

},function (msg) {

alert(msg) // 如果路徑錯了我們彈出 error

})

}

```


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2667353/,如需轉載,請註明出處,否則將追究法律責任。

相關文章