「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
前言
在开始promise之前,我们先来了解两个后面要用到的词
-
生产者代码(producing code):会做一些事儿,并且会需要一些时间的代码。例如,通过网络加载数据的代码。
-
消费者代码(consuming code):想要在“生产者代码”完成工作的第一时间就能获得其工作成果的代码
我们要说的Promise 就是将“生产者代码”和“消费者代码”连接在一起的一个特殊的 JavaScript 对象。
👉 相关内容:说说JavaScript里的回调函数
基本概念
Promise 对象的构造器(constructor)语法
let promise = new Promise(function(resolve, reject) {
// executor(生产者代码)
});
传递给 new Promise 的函数被称为 executor。
executor 会自动运行并尝试执行一项工作。尝试结束后,如果成功则调用 resolve,如果出现 error 则调用 reject。
resolve(value)— 如果任务成功完成并带有结果value。reject(error)— 如果出现了 error,error即为 error 对象。
promise 对象内部属性
由 new Promise 构造器返回的 promise 对象具有以下内部属性:
state— 最初是"pending",然后在resolve被调用时变为"fulfilled"(已兑现),或者在reject被调用时变为"rejected"(已拒绝)。
result— 最初是undefined,然后在resolve(value)被调用时变为value,或者在reject(error)被调用时变为error。
🎨 成功示例:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve("done"), 1000); //成功
});
💡 代码分析:以上示例中, 当 promise 被构造完成时,会自动执行setTimeout函数,1 秒后发出工作已经被完成的信号,改变 promise 对象的状态并带有结果 "done";
state: "fulfilled" result: "done"
🎨 失败示例:
let promise = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error("Whoops!")), 1000); //失败
});
💡 代码分析:以上示例中, 当 promise 被构造完成时,会自动执行setTimeout函数, 1 秒后发出工作已经被完成的信号,并带有 error
state: "rejected" result: error
注意
1、【💥】executor 只能调用一个 resolve 或一个 reject,如果调用多个,后面的会被忽略
let promise = new Promise(function(resolve, reject) {
resolve("done");
reject(new Error("…")); // 被忽略
setTimeout(() => resolve("…")); // 被忽略
});
2、resolve/reject 只需要一个参数(或不包含任何参数),并且将忽略额外的参数。
3、state 和 result 都是内部的,无法直接访问,但可以对它们使用 .then/.catch/.finally 方法。
消费者 .then
Promise 对象充当的是 executor(“生产者代码”)和消费函数之间的连接,后者将接收结果或 error。可以通过使用 .then 方法为消费函数进行注册。
📖 语法:
promise.then(
function(result) { /* 成功 */ },
function(error) { /* 失败 */ }
);
💡 说明:
.then 的第一个参数是一个函数,该函数将在 promise resolved 后运行并接收结果。
.then 的第二个参数也是一个函数,该函数将在 promise rejected 后运行并接收 error。
🎨 示例1:
关键代码:resolve("done!")
🎨 示例2:
关键代码:reject(new Error("Whoops!"))
改写
之前说回调的时候,我们写了一个加载脚本的 loadScript 函数,是这样的
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error(`Script load error for ${src}`));
document.head.append(script);
}
现在用 promise 重写
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Script load error for ${src}`));
document.head.append(script);
});
}
🍒 用法:
let promise
= loadScript("https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js");
promise.then(
script => console.log(`${script.src} is loaded!`),
error => console.log(`Error: ${error.message}`)
);
参考资料:
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐