promise初識

1、涉及技術

jquery、vue、phpphp

2、Promise簡介

MDN官方文檔:Promisehtml

三種狀態:前端

  • Pending(進行中)
  • Resolved(已完成,又稱 Fulfilled)
  • Rejected(已失敗)

只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。vue

3、經常使用方法

  • Promise.resolve()
  • Promise.reject()
  • Promise.prototype.catch()
  • Promise.prototype.then()
  • Promise.all()
  • Promise.race()

4、簡單示例

一、多個Promise使用

var promise = new Promise(function(resolve, reject) {
    setTimeout(function() {
        resolve('hello');
    }, 1000);
});
promise.then(function(str) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(str+' world');
        }, 1000);
    });
}).then(function(str) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(str+' !');
        }, 1000);
    });
}).then(function(str) {
    console.log(str); // 3秒後打印 hello world !
});

二、catch與finaly

var promise = new Promise(function(resolve, reject) {
    setTimeout(function() {
        reject('異步報錯~');
    }, 1000);
}).catch(function(err) { // 捕獲reject暴露的錯誤
    console.log(err);
}).finally(function() { // 無論resolve/reject都執行
    console.log('complete');
});

5、先後端配合

一、單個Promise

後端數據jquery

demo.phpajax

// 獲取隨機字符串
function getRandChar($length) {
    $str = '';
    $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    $max = strlen($strPol)-1;
    for($i=0;$i<$length;$i++){
        $str.=$strPol[rand(0,$max)];
    }
    return $str;
}
if($_GET['action'] == 'test') {
    $data = [
        ["name"=>getRandChar(6), "age"=>rand(1,50)],
        ["name"=>getRandChar(6), "age"=>rand(1,50)],
        ["name"=>getRandChar(6), "age"=>rand(1,50)],
        ["name"=>getRandChar(6), "age"=>rand(1,50)],
    ];
    echo json_encode($data);
}

前端頁面json

demo.html後端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise</title>
    <script src="jquery.min.js"></script>
    <script src="vue.min.js"></script>
</head>
<body>
    
    <div id="app">
        <ul>
            <li v-for="(item, index) in list">{{ index }} {{ item.name }}</li>
        </ul>
    </div>

    <script>
        var app = new Vue({
            el: '#app',
            data: {
                list: []
            },
            mounted: function() {
                var promise1 = new Promise(function(resolve, reject) {
                    $.ajax({
                        type: 'get',
                        url: 'demo.php?action=test',
                        dataType: 'json',
                        success: function(res) {
                            resolve(res);
                        },
                        error: function() {
                            reject('請求報錯~');
                        }
                    });
                });
                // then(fn1, fn2)裏有兩個回調函數,一個是resove,一個是reject
                promise1.then(function(data) {
                    app.list = data;
                }, function(err) {
                    console.log(err);
                });
            }
        });     
    </script>
</body>
</html>

運行結果:promise

圖片描述

二、Promise.all()

Promise.all(p1, p2, ...),此方法須要全部的promise都成功才成功。。
var promise1 = new Promise(function(resolve, reject) {
    $.ajax({
        type: 'get',
        url: 'demo.php?action=test',
        dataType: 'json',
        success: function(res) {
            resolve(res);
        },
        error: function() {
            reject('請求報錯~');
        }
    });
});
var promise2 = new Promise(function(resolve, reject) {
    $.ajax({
        type: 'get',
        url: 'demo.php?action=test',
        dataType: 'json',
        success: function(res) {
            resolve(res);
        },
        error: function() {
            reject('請求報錯~');
        }
    });
});
var promiseAll = Promise.all([promise1, promise2]);
promiseAll.then(function(data) {
    console.log(data);
}, function(err) {
    console.log(err);
});

結果app

圖片描述

若是咱們把其中一個url 改爲 demo2.php?action=test 就會請求失敗~

Promise.all() 和 jquery的$.when() 有些相似

$.when()的寫法

var ajax1 = $.ajax({type: 'get', url: 'demo1.php', data: {}, dataType: 'json'}),
    ajax2 = $.ajax({type: 'get', url: 'demo2.php', data: {}, dataType: 'json'}),
    ajax3 = $.ajax({type: 'get', url: 'demo3.php', data: {}, dataType: 'json'});
$.when([ajax1, ajax2, ajax3]).then(function(data1, data2, data3) {
    console.log(data1, data2, data3);
}, function() {
    console.log('%c 請求報錯~', 'color: red');
});

三、Promise.race()

Promise.race(p1, p2, ...),這個方法會返回率先成功的那個,若是都不成功,則執行reject。
var promise1 = new Promise(function(resolve, reject) {
    $.ajax({
        type: 'get',
        url: 'demo.php?action=test',
        dataType: 'json',
        success: function(res) {
            resolve(res);
        },
        error: function() {
            reject('請求報錯~');
        }
    });
});
var promise2 = new Promise(function(resolve, reject) {
    $.ajax({
        type: 'get',
        url: 'demo.php?action=test',
        dataType: 'json',
        success: function(res) {
            resolve(res);
        },
        error: function() {
            reject('請求報錯~');
        }
    });
});

var promiseRase = Promise.race([promise1, promise2]);
promiseRase.then(function(data) {
    console.log(data);
}, function(err) {
    console.log(err);
});

四、多個ajax請求

var app = new Vue({
    el: '#app',
    data: {
        list: []
    },
    methods: {
        ajaxReq: function(resolve, reject) {
            $.ajax({
                type: 'get',
                url: 'demo.php?action=test',
                dataType: 'json',
                success: function(res) {
                    resolve(res);
                },
                error: function() {
                    reject('請求報錯~');
                }
            });
        }
    },
    mounted: function() {
        var promise1 = new Promise((resolve, reject) => {
            this.ajaxReq(resolve, reject);
        });
        promise1.then((data)=> {
            console.log('第一次:', data);
            return new Promise((resolve, reject) => {
                this.ajaxReq(resolve, reject);
            });
        }).then((data) => {
            console.log('第二次:', data);
            return new Promise((resolve, reject) => {
                this.ajaxReq(resolve, reject);
            });
        }).then((data) => {
            console.log('第三次:', data);
        });
    }
});

這是使用了函數封裝,實際上項目中,可能不是這樣的,連貫操做,多是下一個請求須要上一個請求的返回值

var promise1 = new Promise((resolve, reject) => {
    $.ajax({
        type: 'get',
        url: 'demo.php?action=test',
        dataType: 'json',
        success: function(res) {
            resolve(res, 2);
        },
        error: function() {
            reject('請求報錯~');
        }
    });
});
promise1.then((data)=> {
    if(data.length > 0) {
        return new Promise((resolve, reject) => {
                    $.ajax({
                        type: 'get',
                        url: 'demo.php?action=test',
                        dataType: 'json',
                        success: function(res) {
                            resolve(res.concat(data)); // 由於resolve只能接口一個參數,因此concat了一下
                        },
                        error: function() {
                            reject('請求報錯~');
                        }
                    });
                });   
    }
}).then((data1) => {
    console.log(data1);
});

圖片描述

相關文章
相關標籤/搜索