1. 程式人生 > >Promise 處理非同步問題

Promise 處理非同步問題

實際開發過程中經常會遇到非同步的問題,比如:

       前端向後端發起請求request1,需要獲得資料data1,發起請求request2同時需要請求引數data1,需要獲得資料data2,然後緊接著需要利用data2進行某項計算。。。。理想狀態下,按思路程式碼一路執行下來,沒毛病

     但是!ajax是一個非同步的操作,由於網路延遲,request2執行時很可能request1還沒有返回data1,於是獲取不到data1,request2失敗,SO,data2也獲取不到了。。。然後一路錯下去,當request1返回data1時,程式已經一路崩下去無可挽回了

看一個demo:

function test(resolve, reject){
    let m = 22;;
    setTimeout(function(){
         m +=100;
         if(m<111){
            resolve(m)
        }else{
            reject(111);
        }
        }, 2000);
  console.log("哈哈1");     
}

var p = new Promise(test);
p.then(function(res){
    console.log("成功:",res);
});
p.catch(function(res){
    console.log("失敗:",res);
})
console.log("哈哈2");

// 結果:
//——————————————————————————
// 哈哈1
// 哈哈2
// 失敗: 111

       而一般方法是利用回撥函式來解決非同步問題,然而回調函式這個東西我就感覺思維有點不合正常人類邏輯咯,而且程式碼也比較繁瑣。於是乎,引入Promise是個十分不錯的選擇。顧名思義,Promise即 “承諾” 的意思,既然是承諾,一諾千金那肯定是必須要做的。所以Promise(test)的含義就是承諾在未來的某個時間肯定會執行函式f

       而函式f需要有兩個引數:resolve reject 。這兩個引數都是函式。非同步執行操作執行成功時呼叫resolve函式,失敗時呼叫reject函式。(這兩個函式是js引擎自帶的不用自己定義喲)。而裡面的引數,resolve的引數會傳遞給then的回撥函式,reject的引數會傳遞給catch的回撥函式然後對其進行進一步處理。

或許說到這裡還是沒有感覺Promise有什麼牛逼的地方,那麼,如果比我文章開頭還要複雜點的有多個非同步操作的問題呢?

// 0.5秒後返回input*input的計算結果:
function multiply(input) {
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}

// 3秒後返回input+input的計算結果:
function add(input) {
    return new Promise(function (resolve, reject) {
        console.log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 3000, input + input);
    });
}

var p = new Promise(function (resolve, reject) {
    console.log('start new Promise...');
    resolve(123);
});

p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    console.log('Got value: ' + result);
});

如上述例子,當多個非同步問題是可以採取 p.then().then()..........這樣的寫法,當一個then執行完且執行成功時才會執行下一個then,失敗則停止執行