Promise

狀態

  • pending:等待中,為初始之狀態,即不是 fulfilled 也不是 rejected。
  • fulfilled:已實現,表示操作成功完成。
  • rejected:已拒絕,表示操作失敗。

有可能會發生在履行(fulfill) 或拒絕的 Promise,取決於傳入了什麼給它。

const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
        resolve('success');
        //reject('error');
    },2000);
});

promise.then(function(value) {
  console.log('on fulfillment');
}, function(reason) {
  console.log('on rejection');
});

Promise 是什麼?

  • 它是一種控制流程機制,提供比 callback 更好的一種表達非同步程式邏輯。
  • Promise 的出現,並沒有去除 callback,只是把這些 callback 的協調工作,轉交給了介於我們與其他工作之間的一種「可信任的中介機制」。
  • 它是可以輕易重複用來封裝與合成「未來值」的一種機制。

未來值

等值的承若 (vlue-promise),例如取餐收據。

add(fetchX, fetchY, function(sum){
  console.log(sum);
});

方法

  • Promise.reject(reason)
  • Promise.resolve(value)
  • Promise.all(iterable)
  • Promise.race(iterable)

Promise.resolve(value)

Promise.resolve("Success").then(
  function(value) {
    console.log(value); // Success
  }, 
  function(err) {
    // 不會被呼叫
});
Promise.resolve(new Error("fail")).then(
  function(value) {
    console.log(value); // on fulfilled
  }, 
  function(err) {
    // 不會被呼叫
});

Promise.reject(reason)

代表發生拒絕的情況

Promise.reject('hi').then(
  function(error) {
    // 不會被呼叫
  }, 
  function(error) {
    console.log(error); // Stacktrace
});
Promise.reject(new Error("fail")).then(
  function(error) {
    // 不會被呼叫
  }, 
  function(error) {
    console.log(error); // Stacktrace
});

Promise.all(iterable)

所傳入的所有 prmises 都必須履行 (fulfill),所回傳的 promise 才會履行。

var p1 = Promise.resolve(1);
var p2 = Promise.resolve('Hello World');
var p3 = Promise.resolve('Oops');

Promise.all([p1, p2, p3]).then(function(msg){
  console.log(msg);
});

Promise.all([p1, p2, p3]).catch(function(err){
  console.log(err);
});

Promise.race(iterable)

只要第一個解析的 promise 會勝出,而無論哪個解析結果為何,都會成為所回傳的 promise 的解析結果。

var p1 = Promise.resolve(1);
var p2 = Promise.resolve('Hello World');
var p3 = Promise.resolve('Oops');

Promise.race([p1, p2, p3]).then(function(msg){
  console.log(msg);
});

Promise 原型方法

Promise.prototype.then(onFulfilled, onRejected)

var p1 = new Promise(
  function(resolve, reject) {
    setTimeout(function(){
        resolve("Success!");
    }, 5000);
    // 或 reject ("Error!");
  }
);
  • fulfillment 履行
  • rejection 拒絕
p1.then(
  // fullfilment handler
  function(value) {
    console.log(value); 
  },
  // rejection handler
  function(reason) {
    console.log(reason);
  }
);
p.then(fulfilled);
p.then(fulfilled, rejected);

Promise.prototype.catch(onRejected)

p.catch(rejected);
p.then(null, rejected);

錯誤處理

function func(){
  setTimeout(function(){
    // 故意打錯的
    consoe.log('hi');
  }, 5000);
}

try {
  func();
} catch(err){
  console.log('I am error.', err); // 會發生什麼事?
}

Promise 相容性

Promise 需注意的事項

  • 不要忘最後面要接 catch

只能回傳一個參數

var p1 = new Promise(
  function(resolve, reject) {
    resolve("Success!");
  }
);
var p1 = new Promise(
  function(resolve, reject) {
    let obj = {
      id: 1,
      message: 'success'
    }
    resolve(obj);
  }
);

Weird

假如傳入給 resolve 的是一個立即的非 Promise、非 thenable 的值,那麼 promise 就會以那個值被履行。

var p3 = new Promise(function(resolve, reject){
  resolve('B');
});

var p1 = new Promise(function(resolve, reject){
  resolve(p3);
});

var p2 = new Promise(function(resolve, reject){
  resolve('A'); // immediate value
});

p1.then(function(v){
  console.log(v);
});

p2.then(function(v){
  console.log(v);
});

完整例子

http://jsfiddle.net/ddam2mof/3/

getArticleList().then(function(articles){
    return getArticle(articles[0].id);
}).then(function(article){
    return getAuthor(article);
}).then(function(author){
    alert(author.email);
});

function getAuthor(id){
  return new Promise(function(resolve, reject){
    $.ajax("http://beta.json-generator.com/api/json/get/E105pDLh",{
        author: id
    }).done(function(result){
        resolve(result);
    })
  });
}

function getArticle(id){
  return new Promise(function(resolve, reject){
    $.ajax("http://beta.json-generator.com/api/json/get/EkI02vUn",{
        id: id
    }).done(function(result){
        resolve(result);
    })
  });
}

function getArticleList(){
  return new Promise(function(resolve, reject){
    $.ajax(
    "http://beta.json-generator.com/api/json/get/Ey8JqwIh")
    .done(function(result){
        resolve(result);
    });
  });
}

JQuery

https://jsfiddle.net/daronwolff/n10n17ag/

(function() {
  var restante = 0;
  'use strict';

  function wait() {
    return new Promise(function(done, reject) {
      setTimeout(function() {
        if (restante > 0) {
          done();
        } else {
          reject();
        }
      }, 2000);
    });
  }
  wait().
  then(function() {
    $("h1").text("Ok,Preparando expresso...");
    return wait();
  }).
  then(function() {
    $("h1").text("Listo, tenga su expresos");
    return wait();
  }).
  then(function() {
    restante -= 1;
    $("h1").text("Gracias :)");
  }).
  catch(function() {
    $("h1").text("Lo lamento, no hay expreso :(");
  });
})();

延伸閱讀

更多範例

results matching ""

    No results matching ""