JavaScript Promise

JavaScript Promise 表示一个异步操作最终状态及其结果值。Promise 有一个 then 方法,可以指定一个回调函数,并且 then 方法可以链式调用。

JavaScript Promise 对象表示一个异步操作最终状态及其结果值。Promise 对象有一个 then 方法,可以指定一个回调函数,并且 then 方法可以链式调用。

Promise 语法:

let myPromise = new Promise(function(resolve, reject) {
  // 生产者代码,一般需要一些时间生成数据
  resolve(); // 操作成功时调用
  reject();  // 操作失败时调用
});

// 消费这代码 处理上面产生的数据
myPromise.then(
  function(value) { /* 成功时的回调 */ },
  function(error) { /* 出错时的回调 */ }
);

当生产者代码执行的时候,要么操作成功执行 resolve(),要么操作失败执行 reject()

Promise 对象

一个 Promise 对象有用 3 个状态:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

一个待定状态的 Promise ,要么操作成功变成已兑现,并兑现一个值,要么操作失败被拒绝。

我们不能直接访问 Promise 对象的状态,必须使用 Promise 提供的方法来处理 Promise。

使用 Promise 对象

以下是使用 Promise 的方法:

myPromise.then(
  function(value) { /* 成功时的回调 */ },
  function(error) { /* 出错时的回调 */ }
);

Promise.then() 有两个参数,一个是成功的回调,另一个是失败的回调。两者都是可选的。

function myDisplayer(some) {
  document.getElementById("demo").innerHTML = some;
}

let myPromise = new Promise(function (resolve, reject) {
  let x = 0;

  if (x == 0) {
    resolve("OK");
  } else {
    reject("Error");
  }
});

myPromise.then(
  function (value) {
    myDisplayer(value);
  },
  function (error) {
    myDisplayer(error);
  }
);

Promise 示例

为了演示 Promise 的使用,我们将使用上一章中的回调示例:

  • setTimeout
  • 异步请求

Promise 版 setTimeout

使用回调的示例:

setTimeout(function () {
  myFunction("I love You !!!");
}, 3000);

function myFunction(value) {
  document.getElementById("demo").innerHTML = value;
}

使用 Promise 的示例:

let myPromise = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve("I love You !!");
  }, 3000);
});

myPromise.then(function (value) {
  document.getElementById("demo").innerHTML = value;
});

异步请求

使用回调的示例:

function getFile(myCallback) {
  let req = new XMLHttpRequest();
  req.open("GET", "mycar.html");
  req.onload = function () {
    if (req.status == 200) {
      myCallback(req.responseText);
    } else {
      myCallback("Error: " + req.status);
    }
  };
  req.send();
}

getFile(myDisplayer);

使用 Promise 的示例:

let myPromise = new Promise(function (resolve, reject) {
  let req = new XMLHttpRequest();
  req.open("GET", "mycar.htm");
  req.onload = function () {
    if (req.status == 200) {
      resolve(req.response);
    } else {
      reject("File not Found");
    }
  };
  req.send();
});

myPromise.then(
  function (value) {
    myDisplayer(value);
  },
  function (error) {
    myDisplayer(error);
  }
);

浏览器支持

ECMAScript 2015,也称为 ES6,引入了 JavaScript Promise 对象。

下表定义了第一个完全支持 Promise 对象的浏览器版本:

Chrome Edge Firefox Safari Opera
Chrome 33 Edge 12 Firefox 29 Safari 7.1 Opera 20
2014-02 2015-07 2014-04 2014-09 2014-03