• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

promise知识点

武飞扬头像
一杯茶520
帮助1

一.Promise.race 原理

实现原理

Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i  ) {
      let currentVal = promises[i];
      if (currentVal && typeof currentVal.then == "function") {
        currentVal.then(resolve, reject);
      } else {
        resolve(currentVal);
      }
    }
  });
};

race 只采用第一个成功或者失败的结果

应用场景 (超时处理)

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功");
  }, 3000);
});
function wrap(p) {
  let abort;
  let p1 = new Promise((resolve, reject) => {
    abort = reject;
  });
  let newPromise = Promise.race([p1, p]);
  newPromise.abort = abort;
  return newPromise;
}
let p1 = wrap(p);
p1.then(
  (data) => {
    console.log("success", data);
  },
  (err) => {
    console.log("error", err);
  }
);
setTimeout(() => {
  p1.abort("超过2s了");
}, 2000);

借助 race 的特点,可以实现立即中断 promise 变为失败态。常用作超时操作

二. promisify 原理

const fs = require("fs");
const path = require("path");
function promisify(fn) {
  return function (...args) {
    return new Promise((resolve, reject) => {
      fn(...args, function (err, data) {
        if (err) reject();
        resolve(data);
      });
    });
  };
}
let read = promisify(fs.readFile);
read(path.resolve(__dirname, "name.txt"), "utf8").then((data) => {
  console.log("data", data);
});

三. Promise.all 原理

全部成功才成功,有一个失败就失败,成功的结果是按照调用的顺序来返回的

Promise.all = function (values) {
  // 计数器
  let ret = []; // 最终返回的结果
  let len = values.length;
  return new Promise((resolve, reject) => {
    values.forEach((val, idx) => {
      Promise.resolve(val).then((data) => {
        ret[idx] = data; // 没成功一个和索引对应上
        if (--len === 0) {
          resolve(ret);
        }
      }, reject); // reject => () => {reject()} // 任何一个promise失败嘞 直接就调用外层promise的失败
    });
  });
};
Promise.all([
  // 全部成功才成功,有一个失败就失败,成功的结果是按照调用的顺序来返回的
  fs.readFile(path.resolve(__dirname, "name.txt"), "utf8"),
  fs.readFile(path.resolve(__dirname, "age.txt"), "utf8"),
  123,
])
  .catch((err) => {
    console.log(err, "err");
  })
  .then((data) => {
    console.log(data);
  });
// [ 'zf', '18', 123 ]

四. Promise.finally 原理

就是 then,特点就是无论成功还是失败都会执行的方法

Promise.prototype.finally = function (fn) {
  return this.then(
    (data) => Promise.resolve(fn()).then(() => data),
    // then中的方法 会等待返回的promise执行完毕后继续执行
    // Promise.resolve 要等待fn()执行后的promise执行完毕
    (err) =>
      Promise.resolve(fn()).then(() => {
        throw err;
      })
  );
};
Promise.reject("ok")
  .finally(() => {
    // 就是then 特点就是无论成功还是失败都会执行的方法
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("finally");
        resolve();
      }, 1000);
    });
  })
  .then((data) => {
    console.log("成功", data);
  })
  .catch((err) => {
    console.log("失败", err);
  });
// finally; 失败 ok

五. generator 使用

遍历器的基本实现

const interable = { 0: "a", 1: "b", 2: "c", length: 3 };
interable[Symbol.iterator] = function () {
  let index = 0;
  return {
    // 遍历器对象
    next: () => {
      return { value: this[index], done: index   == this.length };
    },
  };
};
console.log(Array.from(interable)); // ["a", "b", "c"]

如果我们自己去迭代一个对象需要实现一个迭代器接口,自己返回一个具有 next 方法的对象。内部会调用这个 next 方法返回结果包含 value 和 done,当 done 为 true 时迭代完成

通过生成器实现

const iterable = { 0: "a", 1: "b", 2: "c", length: 3 };
iterable[Symbol.iterator] = function* () {
  let index = 0;
  while (index !== this.length) {
    yield this[index  ];
  }
};
console.log([...iterable]); // [ 'a', 'b', 'c' ]

生成器使用

const fs = require("fs/promises");
const path = require("path");
function* readFile() {
  try {
    let data = yield "name.txt";
    let name = yield fs.readFile(path.resolve(__dirname, data), "utf8");
    return name;
  } catch (e) {
    console.log(e, "读取出错");
  }
}
function co(it) {
  return new Promise((resolve, reject) => {
    // 递归回调
    function next(data) {
      // 异步递归处理
      let { value, done } = it.next(data);
      if (!done) {
        Promise.resolve(value).then((data) => {
          // => Promise.resolve(value).then(data => next(data))
          next(data);
        });
      } else {
        resolve(value); // 整个geneator执行完毕了 结束
      }
    }
    next(); // koa express
  });
}
co(readFile()).then((data) => {
  console.log(data);
});

这里我们主是掌握思想,异步迭代的思想。(产生一个迭代函数,当做回调函数使用) promise 链式调用; generator promise co; async await

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbaihe
系列文章
更多 icon
同类精品
更多 icon
继续加载