1. 程式人生 > >es6(一)——promise物件

es6(一)——promise物件

最近處理node邏輯,出現一種狀況:需要同時進行非同步操作,並且後一操作需要前一操作返回值來執行,而express模組呢,只能支援es5,那隻能一層加一層巢狀進去,這對於程式設計了一年多的我來講,有些噁心了(程式設計師都有個通病,那就是矯情~)。索性,promise物件就算為了應付這一狀況的。

含義:promise物件就是用來處理非同步操作的,處理成功了就執行成功操作,處理失敗了就捕捉異常或停止繼續操作。

promise的三種狀態:pending(未處理),fulfilled(處理成功),rejected(處理失敗)。

原型方法:promise.prototype.then()和promise.prototype.catch()

var promise = new Promise(
    (resolve, reject) => {
        reject("this is promise reject catch");
    }
).then(
    (msg) => {
        console.log(msg);   //這裡不會觸發
    }
).catch(
    (err) => {
        console.log(err); // thi is promise reject catch
    }
);
通過上面的例子,then()就是用來處理成功的函式,而catch便是用來捕捉失敗的v函式。

函式方法

promise.all(),promise.race(),promise.resolve(),promise.rejected() 

promise.all()方法,是一種迭代,用來處理併發非同步操作的,它只有在引數內都為fulfilled狀態下,才能返回fulfilled狀態。

var arr = [1, 2, 3];
var promises2 = arr.map(function(e) {
  return new Promise(function(resolve, reject) {
    if (e === 3) {
      reject('rejected');
    }
    resolve(e * 5);
  });
});

Promise.all(promises2).then(function(data) {
  // 這裡不會執行
  console.log(data);
  console.log(arr);
}).catch(function(err) {
  console.log(err); // rejected
});
promise.race()與all方法類似,但它只需要引數中一個有fulfilled狀態便能返回fulfilled狀態。

var p1 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 300, 'p1 doned');
});

var p2 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 50, 'p2 doned');
});

var p3 = new Promise(function(resolve, reject) {
  setTimeout(reject, 100, 'p3 rejected');
});

Promise.race([p1, p2, p3]).then(function(data) {
  // 顯然p2更快,所以狀態變成了fulfilled
  // 如果p3更快,那麼狀態就會變成rejected
  console.log(data); // p2 doned
}).catch(function(err) {
  console.log(err); // 不執行
});
promise.resolve()返回一個成功的方法,可接收then方法的物件,普通值以及promise的例項。

// 引數為普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {
  console.log(data); // 5
});


// 引數為含有then()方法的物件
var obj = {
  then: function() {
    console.log('obj 裡面的then()方法');
  }
};

var p5 = Promise.resolve(obj);
p5.then(function(data) {
  // 這裡的值時obj方法裡面返回的值
  console.log(data); // obj 裡面的then()方法
});


// 引數為Promise例項
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);

p7.then(function(data) {
  // 這裡的值時Promise例項返回的值
  console.log(data); // 7
});
promise.rejected()與 promise.resolve()相反,接受一個引數值。

var p10 = Promise.reject('手動拒絕');
p10.then(function(data) {
  console.log(data); // 這裡不會執行,因為是rejected態
}).catch(function(err) {
  console.log(err); // 手動拒絕
}).then(function(data) {
 // 不受上一級影響
  console.log('狀態:fulfilled'); // 狀態:fulfilled
});

實踐

那如何來實現非同步函式b依賴非同步函式a的結果呢?

function a(){
      return new Promise(function(res,rej){
        $.ajax({
          url:"a",
          type: "GET",
          async:true,
          dataType:"json",
          success:function(data){
            console.log(data,"a");
            res(data);
          }
        })
      });
    }
    function b(data){
      console.log(data,"data");
      return new Promise(function(res,rej){
        $.ajax({
            url:"b",
            type: "POST",
            async:true,
            data:JSON.stringify(data),
            dataType:"json",
            success:function(data){
              console.log(data,"b");
              res();
            }
          })
      });
    }
    $("#btn").click(function(){
      a().then(function (data){
        b(data);
      }).then(function(){
      })
    })