Promise 队列

6 阅读1分钟

核心点:保持promise是连续的,每次promise 返回的是一个新的promise

简单的演示
let promise = Promise.resolve();
    promise
      .then(() => {
        return new Promise((resolve) => {
          setTimeout(function () {
            console.log(1);
            resolve();
          }, 1000);
        });
      })
      .then((res) => {
        return new Promise((resolve) => {
          setTimeout(function () {
            console.log(2);
            resolve();
          }, 1000);
        });
      });
      
打印结果:隔一秒打印1,再隔一秒打印2,等同于

进阶
    let promise = Promise.resolve();
    promise = promise
      .then(() => {
        return new Promise((resolve) => {
          setTimeout(function () {
            console.log(1);
            resolve();
          }, 1000);
        });
      })
      promise.then((res) => {
        return new Promise((resolve) => {
          setTimeout(function () {
            console.log(2);
            resolve();
          }, 1000);
        });
      });

封装
function queue(num) {
      let promise = Promise.resolve();
      num.map((v) => {
        promise = promise.then(() => {
          return new Promise((resolve) => {
            setTimeout(function () {
              console.log(v);
              resolve();
            }, 1000);
          });
        });
      });
    }
queue([1, 2, 3, 4, 5, 6]);
隔一秒打印一下   // 1 2 3 4 5 6

实际应用场景,发送请求

    function queue(num) {
      let promise = Promise.resolve();
      num.map((v) => {
        promise = promise.then(() => {
          return v();
        });
      });
    }
    const p1 = function () {
      return new Promise((resolve) => {
        setTimeout(function () {
          console.log("p1");
          resolve();
        }, 1000);
      });
    };
    const p2 = function () {
      return new Promise((resolve) => {
        setTimeout(function () {
          console.log("p2");
          resolve();
        }, 1000);
      });
    };
    queue([p1, p2]);

reduce 版本

 function queue(num) {
      num.reduce((promise, n) => {
        return promise.then(() => {
          return n();
        });
      }, Promise.resolve());
    }
    const p1 = function () {
      return new Promise((resolve) => {
        setTimeout(function () {
          console.log("p1");
          resolve();
        }, 1000);
      });
    };
    const p2 = function () {
      return new Promise((resolve) => {
        setTimeout(function () {
          console.log("p2");
          resolve();
        }, 1000);
      });
    };
    queue([p1, p2]);

实际使用案例

  1. 在本地搭建服务
const express = require("express");
const cors = require("cors");
const app = express();
const port = 3000;
app.use(cors());
app.use(express.json()); // 解析 JSON 请求体
app.get("/user/:username", (req, res) => {
  setTimeout(function () {
    res.send(req.params.username);
  }, 1000);
});
app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

2.请求

class User {
      ajax(user) {
        return new Promise((resolve, reject) => {
          let xhr = new XMLHttpRequest();
          xhr.open("GET", `http://localhost:3000/user/${user}`);
          xhr.send();
          xhr.onload = function () {
            if (this.status === 200) {
              resolve(this.response);
            } else if (this.status === 404) {
              reject(new HttpError("用户不存在"));
            }
          };
          xhr.onerror = function () {
            reject(this);
          };
        });
      }
      render(users) {
        users.reduce((promise, user) => {
          return promise
            .then(() => {
              return this.ajax(user);
            })
            .then((res) => {
              return this.view(res)
            });
        }, Promise.resolve());
      }
      view(res) {
        return new Promise((resolve) => {
          const h2 = document.createElement("h2");
          h2.innerHTML = res;
          document.body.appendChild(h2);
          resolve();
        });
      }
    }
    new User().render(["小明", "小红"]);