promise知识点
一.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
系列文章
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01