JavaScript 承诺


目录

    显示目录

“我保证一个结果!”

“生成代码”是可能需要一些时间的代码

“消耗代码”是必须等待结果的代码

Promise 是一个连接生成代码和使用代码的 JavaScript 对象

JavaScript Promise 对象

JavaScript Promise 对象包含生成代码和对消费代码的调用:

Promise 语法

let myPromise = new Promise(function(myResolve, myReject) {
// "Producing Code" (May take some time)

  myResolve(); // when successful
  myReject();  // when error
});

// "Consuming Code" (Must wait for a fulfilled Promise)
myPromise.then(
  function(value) { /* code if successful */ },
  function(error) { /* code if some error */ }
);

当生成代码获得结果时,它应该调用两个回调之一:

Success

myResolve(结果值)

Error

myReject(错误对象)


Promise 对象属性

JavaScript Promise 对象可以是:

  • 待办的

  • 实现了

  • 拒绝

Promise 对象支持两个属性:stateresult

当 Promise 对象处于“待定”(工作)状态时,结果是未定义的。

当 Promise 对象被“履行”时,结果是一个值。

当 Promise 对象被“拒绝”时,结果是一个错误对象。

"pending"

不明确的

"fulfilled"

结果值

"rejected"

一个错误对象

您无法访问 Promise 属性 stateresult

您必须使用 Promise 方法来处理 Promise。


承诺如何做

以下是如何使用 Promise:

myPromise.then(
  function(value) { /* code if successful */ },
  function(error) { /* code if some error */ }
);

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

两者都是可选的,因此您只能添加成功或失败的回调。

例子

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

let myPromise = new Promise(function(myResolve, myReject) {
  let x = 0;

// The producing code (this may take some time)

  if (x == 0) {
    myResolve("OK");
  } else {
    myReject("Error");
  }
});

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

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Promise</h2>

<p id="demo"></p>

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

let myPromise = new Promise(function(myResolve, myReject) {
  let x = 0;

// some code (try to change x to 5)

  if (x == 0) {
    myResolve("OK");
  } else {
    myReject("Error");
  }
});

myPromise.then(
  function(value) {myDisplayer(value);},
  function(error) {myDisplayer(error);}
);
</script>

</body>
</html>


JavaScript Promise 示例

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

  • 等待超时

  • 等待文件


等待超时

使用回调的示例

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

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

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Functions</h1>
<h2>setInterval() with a Callback</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

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

function myFunction(value) {
  document.getElementById("demo").innerHTML = value;
}
</script>

</body>
</html>

使用 Promise 的示例

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

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

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Promise</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

<script>
const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(function(){ myResolve("I love You !!"); }, 3000);
});

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

</body>
</html>

等待文件

使用回调的示例

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);

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Callbacks</h2>

<p id="demo"></p>

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

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

getFile(myDisplayer); 
</script>

</body>
</html>

使用 Promise 的示例

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

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

自己尝试一下 →

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Promise</h2>

<p id="demo"></p>

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

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

myPromise.then(
  function(value) {myDisplayer(value);},
  function(error) {myDisplayer(error);}
);
</script>

</body>
</html>

浏览器支持

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

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

Chrome 33 Edge 12 Firefox 29 Safari 7.1 Opera 20
Feb, 2014 Jul, 2015 Apr, 2014 Sep, 2014 Mar, 2014