任务队列

Promise 的作用

Promise 就是为了解决“回调地狱”问题的,它可以将异步操作的处理变得很优雅。回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象 Promise 可以支持多个并发的请求,获取并发请求中的数据这个 Promise 可以解决异步的问题,本身不能说 Promise 是异步的。

Promise 状态:pending - [待定]初始状态、fulfilled - [实现]操作成功、rejected - [被否决]操作失败 Promise 会根据状态来确定执行哪个方法 Promise 实例化时状态默认为 pending 的,如异步状态异常rejected,反之fulfilled
注意:状态转化是单向的,不可逆转,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending),而且只能是从 pending 到 fulfilled 或者 rejected

Promise 的基本用法

  1. {
  2. // 基本定义
  3. let ajax = function (callback) {
  4. console.log("执行"); // 执行
  5. setTimeout(function () {
  6. callback && callback.call();
  7. }, 1000);
  8. };
  9. ajax(function () {
  10. console.log("timeout1"); // timeout1
  11. });
  12. }
  13. {
  14. let ajax = function () {
  15. console.log("执行2");
  16. return new Promise(function (resolve, reject) {
  17. setTimeout(function () {
  18. resolve();
  19. }, 1000);
  20. });
  21. };
  22. ajax().then(function () {
  23. console.log("Promise", "timeout2"); // Promise timeout2
  24. });
  25. }
  26. {
  27. let ajax = function () {
  28. console.log("执行3"); // 执行3
  29. return new Promise(function (resolve, reject) {
  30. setTimeout(function () {
  31. resolve();
  32. }, 1000);
  33. });
  34. };
  35. ajax()
  36. .then(function () {
  37. return new Promise(function (resolve, reject) {
  38. setTimeout(function () {
  39. resolve();
  40. }, 2000);
  41. });
  42. })
  43. .then(function () {
  44. console.log("timeout3"); // timeout3
  45. });
  46. }
  47. {
  48. let ajax = function (num) {
  49. console.log("执行4"); // 执行4 执行4
  50. return new Promise(function (resolve, reject) {
  51. if (num > 5) {
  52. resolve();
  53. } else {
  54. throw new Error("出错了");
  55. }
  56. });
  57. };
  58. ajax(6)
  59. .then(function () {
  60. console.log("log", 6); // log 6
  61. })
  62. .catch(function (err) {
  63. console.log("catch", err);
  64. });
  65. ajax(3)
  66. .then(function () {
  67. console.log("log", 3);
  68. })
  69. .catch(function (err) {
  70. console.log("catch", err); // catch [Error: 出错了]
  71. });
  72. }

Promise.all() 批量执行

Promise.all([a1, a2, a3])用于将多个promise实例,包装成一个新的Promise实例,返回的实例就是普通的promise 它接收一个数组作为参数 数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变

当所有的子Promise都完成,该Promise完成,返回值是全部值得数组

有任何一个失败,该Promise失败,返回值是第一个失败的子Promise结果

  1. {
  2. // 所有图片加载完在添加到页面
  3. function loadImg(src) {
  4. return new Promise((resolve, reject) => {
  5. let img = document.createElement("img");
  6. img.src = src;
  7. img.onload = function () {
  8. resolve(img);
  9. };
  10. img.onerror = function (err) {
  11. reject(err);
  12. };
  13. });
  14. }
  15. function showImgs(imgs) {
  16. imgs.forEach(function (img) {
  17. document.body.appendChild(img);
  18. });
  19. }
  20. Promise.all([
  21. loadImg("https://gitee.com/uploads/85/1803985_WuChenDi.png?1525674217"),
  22. loadImg("http://i4.buimg.com/567751/2b07ee25b08930ba.png"),
  23. loadImg("http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png"),
  24. ]).then(showImgs);
  25. }

Promise.race()

类似于Promise.all() ,区别在于它有任意一个完成就算完成

  1. {
  2. // 有一个图片加载完就添加到页面
  3. function loadImg(src) {
  4. return new Promise((resolve, reject) => {
  5. let img = document.createElement("img");
  6. img.src = src;
  7. img.onload = function () {
  8. resolve(img);
  9. };
  10. img.onerror = function (err) {
  11. reject(err);
  12. };
  13. });
  14. }
  15. function showImgs(img) {
  16. let p = document.createElement("p");
  17. p.appendChild(img);
  18. document.body.appendChild(p);
  19. }
  20. Promise.race([
  21. loadImg("https://gitee.com/uploads/85/1803985_WuChenDi.png?1525674217"),
  22. loadImg("http://i4.buimg.com/567751/2b07ee25b08930ba.png"),
  23. loadImg("http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png"),
  24. ]).then(showImgs);
  25. }

promise问题

  1. 一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来
  2. 错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  3. Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)