当前位置:首页 > 简单说说Promise

简单说说Promise

发布于 2018-04-17 阅读 501 次 Javascript ES6

js里面存在很多异步操作,大多时候我们需要等待异步操作完成之后再做一些事情,一般来说,最容易想到是回调函数,这个是我们常用的方式。但是如果我们回调里面又是一个回调呢,然后又一层回调,这样我们得代码就会变成倒金字塔形式,既不好看,又不易读,幸好ES6出现了Promise,使用promise我们可以像jquery那样链式调用。

先看一个简单的例子

  1. new Promise(
  2. function(){
  3. var a = 10;
  4. setTimeout(function(){
  5. if(a>10){
  6. console.log(1);
  7. }else{
  8. console.log(2);
  9. }
  10. },3000);
  11. }
  12. )

把这个输入到console里面我们发现直接会输出结果,当然我们不希望他直接执行,所以我们可以把这个放在一个函数中:

  1. function Demo(){
  2. return new Promise(
  3. function(){
  4. var a = 10;
  5. setTimeout(function(){
  6. if(a>10){
  7. console.log(1);
  8. }else{
  9. console.log(2);
  10. }
  11. },3000);
  12. }
  13. )
  14. }
  15. Demo();

resolve 和 reject

Promise对象接收一个函数作为参数,这个函数有两个参数,resolve和reject,我们姑且认为resolve表示成功,reject表示失败,当然这个比喻并不是恰当的。
resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。

  1. function Demo(){
  2. return new Promise(
  3. function(resolve, reject){
  4. var a = 10;
  5. setTimeout(function(){
  6. if(a>10){
  7. console.log(1);
  8. resolve('>10');
  9. }else{
  10. console.log(2);
  11. reject('<10');
  12. }
  13. },3000);
  14. }
  15. )
  16. }

Promise.prototype.then

then方法返回的是一个新的Promise实例

  1. var p = Demo().then(function(data){
  2. console.log(data);
  3. return Demo2();
  4. })
  5. console.log(p instanceof Promise)
  6. //true

then方法接收1或者2个函数作为参数,当值传递一个参数时,这个函数只有Promise是fullfield状态的时候会进入这个函数,是rejected状态的时候会报错,所以一般我们传递两个参数比较好,传递两个参数第一个是fullfilled状态进入,第二个是rejected状态进入。

  1. Demo().then(function(data){
  2. console.log(data);
  3. },function(data){
  4. console.log(data);
  5. });
  6. //输出
  7. //2
  8. //<10

Promise链式调用

虽然then方法会返回一个Promise对象,但是这个对象是一个新的Promise对象不再是原来那个Promise对象,不一定符合我们的需求,所以我们可以在then的参数函数里面return我们希望的Promise对象。

  1. Demo1().then(function(data){
  2. console.log(data);
  3. return Demo2();
  4. })
  5. .then(function(data){
  6. console.log(data)
  7. return Demo3();
  8. })
  9. .then(function(data){
  10. console.log(data)
  11. });
  12. function Demo1(){
  13. return new Promise(
  14. function(resolve, reject){
  15. var a = 20;
  16. setTimeout(function(){
  17. if(a>10){
  18. console.log("Demo1执行完成");
  19. resolve('Demo1 resolve>10');
  20. }else{
  21. console.log(1);
  22. reject("Demo1 reject<10");
  23. }
  24. },3000);
  25. }
  26. )
  27. }
  28. function Demo2(){
  29. return new Promise(
  30. function(resolve, reject){
  31. var a = 20;
  32. setTimeout(function(){
  33. if(a>10){
  34. console.log("Demo2执行完成");
  35. resolve('Demo2 resolve>10');
  36. }else{
  37. console.log(2);
  38. reject("Demo2 reject<10");
  39. }
  40. },3000);
  41. }
  42. )
  43. }
  44. function Demo3(){
  45. return new Promise(
  46. function(resolve, reject){
  47. var a = 20;
  48. setTimeout(function(){
  49. if(a>10){
  50. console.log("Demo3执行完成");
  51. resolve('Demo3 resolve>10');
  52. }else{
  53. console.log(3);
  54. reject("Demo3 reject<10");
  55. }
  56. },3000);
  57. }
  58. )
  59. }
  60. // 输出结果
  61. // Demo1执行完成
  62. // Demo1 resolve>10
  63. // Demo2执行完成
  64. // Demo2 resolve>10
  65. // Demo3执行完成
  66. // Demo3 resolve>10

Promise.all

接收一个数组,会执行完所有的异步操作之后,将结果放入results数组中
Promise.all将会返回一个新的Promise对象,该对象的状态由参数数组中的所有Promise对象状态决定,只要有一个是rejected则返回的Promise对象是rejected状态,所有Promise参数都为resolved则返回的Promise对象是resolved状态。

  1. Promise.all([Demo1(),Demo2(),Demo3()])
  2. .then(function(results){
  3. console.log(results);
  4. })

如果promise.all里面的Promise对象有一个是rejected 的状态则进入不了then函数,这个时候我们需要用catch来捕获这个错误,否则就会报错。

  1. Promise.all([Demo1(),Demo2(),Demo3()])
  2. .then(function(results){
  3. console.log(results);
  4. })
  5. .catch(function(e){
  6. console.log(e);
  7. })