秦皇岛网站制作专家,北京建设网经济适用房,深圳服务好的网站建设,wordpress打开文件明明白白Promise (Park One)
Promise是一种用于处理异步操作的特殊对象。它代表了一个尚未完成但最终会完成的操作#xff0c;并可以在操作完成后返回结果或错误。
Promise有三种状态#xff1a;pending#xff08;进行中#xff09;、fulfilled#xff08;已完成#…明明白白Promise (Park One)
Promise是一种用于处理异步操作的特殊对象。它代表了一个尚未完成但最终会完成的操作并可以在操作完成后返回结果或错误。
Promise有三种状态pending进行中、fulfilled已完成和rejected已拒绝。当一个Promise被创建时它处于pending状态。操作可以是异步的当操作成功完成时Promise将转为fulfilled状态并提供相应的结果。相反如果操作失败则Promise将转为rejected状态并提供错误的原因。
使用Promise可以通过链式调用then()方法来处理异步操作的结果。then()方法接受两个回调函数作为参数一个用于处理操作成功完成时的结果另一个用于处理操作被拒绝时的错误。这种链式调用的方式使得代码更加清晰和易于维护。
除了then()方法Promise还提供了其他方法如catch()用于捕获错误finally()用于指定无论Promise状态如何都要执行的操作。
Promise的出现使得JavaScript中的异步编程更加优雅和可读避免了回调地狱callback hell的问题。它已经成为现代JavaScript中处理异步操作的一种标准方式。
Promise 在各种开源库中已经实现现在标准化后被浏览器默认支持。
传统实现代码会陷入回调地狱的例子
function getUser(userId, callback) {// 异步操作获取用户数据setTimeout(() {const user { id: userId, name: John };callback(user);}, 1000);
}function getPosts(user, callback) {// 异步操作获取用户的帖子数据setTimeout(() {const posts [Post 1, Post 2, Post 3];callback(posts);}, 1000);
}function getComments(post, callback) {// 异步操作获取帖子的评论数据setTimeout(() {const comments [Comment 1, Comment 2, Comment 3];callback(comments);}, 1000);
}getUser(1, (user) {getPosts(user, (posts) {getComments(posts[0], (comments) {console.log(comments);});});
});我们需要获取用户数据、帖子数据和评论数据。由于这些操作都是异步的我们使用了多个嵌套的回调函数来处理它们。这样的代码结构难以阅读和维护尤其是在处理更复杂的异步操作时。
Promise 的优点之一是可以通过链式调用来避免回调地狱问题使代码结构更加清晰和可读。一个 promise 必须有一个 then 方法用于处理状态改变。
Promise 包含pending、fulfilled、rejected三种状态
pending 指初始等待状态初始化 promise 时的状态resolve 指已经解决将 promise 状态设置为fulfilledreject 指拒绝处理将 promise 状态设置为rejectedpromise 是生产者通过 resolve 与 reject 函数告之结果promise 非常适合需要一定执行时间的异步任务
状态一旦改变将不可更改promise 没有使用 resolve 或 reject 更改状态时状态为 pending。
console.log(new Promise((resolve, reject) {});
); //Promise {pending}当更改状态后
console.log(new Promise((resolve, reject) {resolve(fulfilled);})
); //Promise {resolved: fulfilled}console.log(new Promise((resolve, reject) {reject(rejected);})
); //Promise {rejected: rejected}promise 创建时即立即执行即同步任务then 会放在异步微任务中执行需要等同步任务执行后才执行。
let promise new Promise((resolve, reject) {resolve(fulfilled);console.log(success);
});
promise.then(msg {console.log(msg);
});
console.log(ss-s.cc);
promise 操作都是在其他代码后执行下面会先输出 ss-s.cc 再弹出 successpromise 的 then、catch、finally 的方法都是异步任务
程序需要将主任务执行完成才会执行异步队列任务
const promise new Promise(resolve resolve(success));
promise.then(alert);
alert(ss-s.cc);
promise.then(() {alert(success);
});下例在三秒后将 Promise 状态设置为 fulfilled 然后执行 then 方法
new Promise((resolve, reject) {setTimeout(() {resolve(fulfilled);}, 3000);
}).then(msg {console.log(msg);},error {console.log(error);}
);状态被改变后就不能再修改了下面先通过resolve 改变为成功状态表示promise 状态已经完成就不能使用 reject 更改状态了
new Promise((resolve, reject) {resolve(操作成功);reject(new Error(请求失败));
}).then(msg {console.log(msg);},error {console.log(error);}
);动态改变
如果你想在没有使用 Promise 的情况下动态改变异步操作的处理方式一个可能的方法是使用回调函数作为参数并在需要改变处理方式时更改回调函数。
function asyncOperation(callback) {setTimeout(() {const data Async data;callback(data);}, 1000);
}// 初始情况下使用默认的回调函数处理异步操作结果
asyncOperation((result) {console.log(默认处理方式:, result);
});// 动态改变处理方式使用新的回调函数处理异步操作结果
const newCallback (result) {console.log(新的处理方式:, result.toUpperCase());
};asyncOperation(newCallback);我们使用默认的回调函数来处理异步操作结果。然后我们定义了一个新的回调函数 newCallback它会将结果转换为大写形式。通过将新的回调函数传递给 asyncOperation 函数我们可以动态地改变处理方式。
使用Promise可以更方便地实现动态改变异步操作的处理方式。
function asyncOperation() {return new Promise((resolve, reject) {setTimeout(() {const data Async data;resolve(data);}, 1000);});
}// 初始情况下使用默认的处理方式处理异步操作结果
asyncOperation().then((result) {console.log(默认处理方式:, result);});// 动态改变处理方式使用新的处理方式处理异步操作结果
const newHandler (result) {console.log(新的处理方式:, result.toUpperCase());
};// 创建一个新的 Promise并在其上添加新的处理方式
const newPromise asyncOperation().then(newHandler);// 在新的 Promise 上继续添加其他处理方式
newPromise.then((result) {console.log(额外的处理方式:, result.length);});then的介绍及使用方法
什么是thenthen() 是 Promise 对象上的方法之一用于处理 Promise 的成功状态fulfilled。它接受两个参数一个是处理成功状态的回调函数另一个是处理失败状态rejected的回调函数可选。
语法
promise.then(onFulfilled, onRejected)onFulfilled 是一个函数它会在 Promise 对象被成功解决时调用并接收解决fulfilled状态的值作为参数。这个函数可以处理异步操作的结果执行其他操作或者返回一个新的值或 Promise 对象。onRejected 是一个可选的函数它会在 Promise 对象被拒绝rejected时调用并接收拒绝状态的原因作为参数。这个函数可以处理错误进行错误处理或返回一个新的错误。
.then() 方法返回一个新的 Promise 对象可以通过链式调用多个 .then() 方法来串联处理多个异步操作的结果。
const promise new Promise((resolve, reject) {setTimeout(() {const randomNum Math.random();if (randomNum 0.5) {resolve(randomNum); // 操作成功完成返回结果} else {reject(new Error(操作失败)); // 操作被拒绝返回错误}}, 1000);
});promise.then((result) {console.log(操作成功:, result);return result * 2; // 返回一个新的值},(error) {console.log(操作失败:, error);throw new Error(新的错误); // 抛出一个新的错误}
).then((newResult) {console.log(新的操作成功:, newResult);},(newError) {console.log(新的操作失败:, newError);}
);then的链式调用
可以在一个 Promise 对象上多次调用 .then() 方法以便依次处理异步操作的结果。每个 .then() 方法都返回一个新的 Promise 对象使得你可以在后续的 .then() 方法中继续处理结果形成一个链式的处理流程。
function asyncOperation() {return new Promise((resolve, reject) {setTimeout(() {const data Async data;resolve(data);}, 1000);});
}asyncOperation().then((result) {console.log(第一个处理步骤:, result);return result.toUpperCase();}).then((result) {console.log(第二个处理步骤:, result);return result.split( );}).then((result) {console.log(第三个处理步骤:, result);return result.reverse();}).then((result) {console.log(最终结果:, result);}).catch((error) {console.log(发生错误:, error);});注意点 返回值传递.then() 方法可以返回一个值或一个新的 Promise 对象。如果回调函数返回一个值该值将被包装在一个已解决fulfilled状态的 Promise 对象中并作为下一个 .then() 方法的输入。如果回调函数返回一个 Promise 对象下一个 .then() 方法将等待该 Promise 对象解决并将其解决值作为输入。 异步操作的顺序.then() 方法是异步的它们会在 Promise 的解决fulfilled状态时被调用而不会阻塞后续代码的执行。因此在链式调用中的每个 .then() 方法中的代码可能会在其他 .then() 方法之前或之后执行。确保你理解和处理好异步操作的顺序和依赖关系。 错误处理.then() 方法链中的任何一个步骤发生错误时错误会被传递到后续的 .catch() 方法或链中的下一个 .then() 方法的错误处理回调函数中。使用 .catch() 方法来捕获和处理链式调用中的错误确保错误被适当地处理和传递。 异常处理如果在 .then() 方法中的回调函数中抛出异常使用 throw 语句异常会被自动捕获并传递给后续的 .catch() 方法或链中的下一个 .then() 方法的错误处理回调函数中。 链式调用的返回值.then() 方法返回一个新的 Promise 对象它代表了当前 .then() 方法的处理结果。这使得你可以通过链式调用多个 .then() 方法来形成一个处理流程。同时返回的 Promise 对象可以用于后续的 .then() 方法的调用或错误处理。 注意 Promise 链的结束在 .then() 方法链中确保在链的最后使用 .catch() 方法或 .finally() 方法来处理最终的成功或失败状态以避免未处理的 Promise 拒绝rejected状态导致的未捕获错误。
catch Promise 对象的 .catch() 方法用于捕获和处理 Promise 链中发生的错误。当 Promise 链中的任何一个 Promise 被拒绝rejected时错误会被传递到 .catch() 方法中进行处理。 .catch() 方法接受一个回调函数作为参数该回调函数会在 Promise 被拒绝时被调用。回调函数可以接收一个参数即拒绝的原因通常是一个 Error 对象并在该函数中执行错误处理逻辑。
fetch(https://api.example.com/data).then(response {// 处理响应return response.json();}).then(data {// 处理数据console.log(data);}).catch(error {// 处理错误console.error(发生错误:, error);});
如果 fetch() 请求失败或者 .then() 中的任何一个操作抛出异常错误将被传递到 .catch() 中进行处理。您可以在 .catch() 回调函数中执行适当的错误处理例如打印错误消息或执行备选操作。
使用 .catch() 方法可以有效地捕获和处理 Promise 链中的错误确保代码在出现异常情况时具有适当的容错和错误处理机制。
catch 用于失败状态的处理函数等同于 then(null,reject){}
建议使用 catch 处理错误将 catch 放在最后面用于统一处理前面发生的错误
const promise new Promise((resolve, reject) {reject(new Error(Notice: Promise Exception));
}).catch(msg {console.error(msg);
});catch 可以捕获之前所有 promise 的错误所以建议将 catch 放在最后。下例中 catch 也可以捕获到了第一个 then 返回 的 promise 的错误。
new Promise((resolve, reject) {resolve();
})
.then(() {return new Promise((resolve, reject) {reject(.then );});
})
.then(() {})
.catch(msg {console.log(msg);
});
错误是冒泡的操作的下面没有任何一个then 定义第二个函数将一直冒泡到 catch 处理错误
new Promise((resolve, reject) {reject(new Error(请求失败));
})
.then(msg {})
.then(msg {})
.catch(error {console.log(error);
});
catch 也可以捕获对 then 抛出的错误处理new Promise((resolve, reject) {resolve();
})
.then(msg {throw new Error(这是then 抛出的错误);
})
.catch(() {console.log(33);
});
也可以捕获其他错误下面在 then 中使用了未定义的变量将会把错误抛出到 catch
new Promise((resolve, reject) {resolve(success);
})
.then(msg {console.log(a);
})
.catch(reason {console.log(reason);
});使用建议 建议将错误要交给catch处理而不是在then中完成不建议使用下面的方式管理错误
new Promise((resolve, reject) {reject(new Error(请求失败));
}).then(msg {console.log(msg);},error {console.log(error);}
);处理机制,在 promise 中抛出的错误也会被catch 捕获
const promise new Promise((resolve, reject) {throw new Error(fail);
}).catch(msg {console.log(msg.toString());
});注意可以将上面的理解为如下代码可以理解为内部自动执行 try…catch
const promise new Promise((resolve, reject) {try {throw new Error(fail);} catch (error) {reject(error);}
}).catch(msg {console.log(msg.toString());
});但像下面的在异步中 throw 将不会触发 catch而使用系统错误处理
const promise new Promise((resolve, reject) {setTimeout(() {throw new Error(fail);}, 2000);
}).catch(msg {console.log(msg);
});下面在then 方法中使用了没有定义的hd函数也会抛除到 catch 执行可以理解为内部自动执行 try…catch
const promise new Promise((resolve, reject) {resolve();
})
.then(() {hd();
})
.catch(msg {console.log(msg.toString());
});
在 catch 中发生的错误也会抛给最近的错误处理const promise new Promise((resolve, reject) {reject();
})
.catch(msg {hd();
})
.then(null, error {console.log(error);
});fanlly的介绍与用法
Promise 对象的 .finally() 方法用于指定不论 Promise 是否成功完成或被拒绝都要执行的逻辑。无论 Promise 的状态如何.finally() 方法都会在 Promise 链中的最后执行。
.finally() 方法接受一个回调函数作为参数该回调函数在 Promise 完成或被拒绝时被调用。它不接收任何参数因此无法获取 Promise 的结果或拒绝原因仅用于执行一些清理操作或在 Promise 完成后执行一些必要的逻辑。
fetch(https://api.example.com/data).then(response {// 处理响应return response.json();}).then(data {// 处理数据console.log(data);}).catch(error {// 处理错误console.error(发生错误:, error);}).finally(() {// 执行清理操作或其他逻辑console.log(完成处理);});注意无论状态是resolve 或 reject 都会执行此动作finally 与状态无关。
图片加载的综合例子 function loadImage(url) {return new Promise((resolve, reject) {const img new Image();img.onload function() {resolve(img);};img.onerror function() {reject(new Error(图片加载失败));};img.src url;});
}function displayImage(image) {const container document.getElementById(image-container);container.appendChild(image);
}function handleImageLoad(url) {loadImage(url).then(image {displayImage(image);}).catch(error {console.error(加载图片出错:, error);}).finally(() {console.log(清理工作完成);});
}// 调用示例
const imageUrl https://example.com/image.jpg;
handleImageLoad(imageUrl);
首先定义了 loadImage() 函数它接受一个图片的URL作为参数并返回一个 Promise 对象。在 Promise 的构造函数中我们创建一个新的 Image 对象并设置其 onload 和 onerror 事件处理程序。当图片加载成功时我们调用 resolve() 方法将加载的图片对象传递给 .then() 方法。当图片加载失败时我们调用 reject() 方法将一个错误对象传递给 .catch() 方法。
在 handleImageLoad() 函数中我们调用 loadImage() 函数来加载图片并使用 .then() 方法来处理加载成功的情况。在 .then() 方法的回调函数中我们调用 displayImage() 函数来显示加载的图片。如果加载出现错误我们使用 .catch() 方法来处理错误情况。无论加载成功还是失败我们都使用 .finally() 方法来进行清理工作。
欢迎点赞关注 谢谢