回调地狱

回调地狱就是在实现完成一个请求之后再发送另一个请求这样的需求的时候,造成的极不易维护的代码:在回调中不停的嵌套回调。

  1. $.ajax({
  2. url: './aa.json',
  3. type: 'get',
  4. success: result => {
  5. $.ajax({
  6. url: './bb.json',
  7. type: 'get',
  8. success: result => {
  9. $.ajax({
  10. url: './bb.json',
  11. type: 'get',
  12. success: result => {
  13. //...
  14. }
  15. });
  16. }
  17. });
  18. }
  19. });

基于发布订阅模式解决回调地狱

基于发布订阅管理起来较为方便,但是,你需要回调一个事情,就需要创建一个计划表。

  1. let $planA = $.Callbacks(),
  2. $planB = $.Callbacks();
  3. $.ajax({
  4. url: './data.json',
  5. type: 'get',
  6. success: result => {
  7. $planA.fire(result);
  8. }
  9. });
  10. $planA.add(result => {
  11. $.ajax({
  12. url: './data2.json',
  13. type: 'get',
  14. success: result => {
  15. $planB.fire(result);
  16. }
  17. })
  18. });
  19. $planB.add(result=>{
  20. //...
  21. });

基于 Promise 解决回调地狱

这是一个最完美的解决方案,可以清晰的看出代码的流程,用法也特别简单。

  1. //=> 将三个异步操作独立封装,都返回 Promise 实例
  2. let queryA = function queryA() {
  3. return new Promise((resolve, reject) => {
  4. $.ajax({
  5. url: 'data.json',
  6. type: 'get',
  7. success(result) {
  8. resolve(result);
  9. },
  10. error(msg) {
  11. reject(msg);
  12. }
  13. });
  14. });
  15. }
  16. let queryB = function queryA() {
  17. return new Promise((resolve, reject) => {
  18. $.ajax({
  19. url: 'data.json',
  20. type: 'get',
  21. success(result) {
  22. resolve(result);
  23. },
  24. error(msg) {
  25. reject(msg);
  26. }
  27. });
  28. });
  29. }
  30. let queryC = function queryA() {
  31. return new Promise((resolve, reject) => {
  32. $.ajax({
  33. url: 'data.json',
  34. type: 'get',
  35. success(result) {
  36. resolve(result);
  37. },
  38. error(msg) {
  39. reject(msg);
  40. }
  41. });
  42. });
  43. }
  44. //=> 再利用 promise 管控这个三个异步操作
  45. let promise = queryA();
  46. promise.then(result => {
  47. console.log('A', result);
  48. //=> 上一个 then 中函数手动返回一个新的 Promise 实例管理一个异步操作
  49. // 下一个 then 会等上一个 then 中的异步成功后再执行
  50. return queryB();
  51. }).then(result => {
  52. console.log('B', result);
  53. return queryC();
  54. }).then({
  55. console.log('C', result);
  56. });