异步?
是在事件处理过程中,为解决线程堵塞的一个思想;
在执行耗时且不立即返回结果的代码时,不会阻塞后面的代码操作,一般在执行完成后会调后续函数进行执行,任务的排列顺序和执行顺序不一致,js 中异步任务由事件循环处理
promise?
promise 举个例子就是:你是一个歌手,粉丝们一直向你了解新歌什么时候发版;你为了减轻这种困扰;你让粉丝们关注**,在新歌发布的时候会进行发布,关注的粉丝都会收到通知;在这里需要时间来执行的操作就是“歌手新歌发布”;等待操作结束后需要执行的后续函数、操作就是“粉丝收到新歌发布收到通知”
基本用法
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
resolve 函数的作用是,将 Promise 对象的状态从“未完成”变为“成功”(即从 Pending 变为 Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject 函数的作用是,将 Promise 对象的状态从“未完成”变为“失败”(即从 Pending 变为 Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
then
Promise 实例生成以后,可以用 then 方法分别指定 Resolved 状态和 Rejected 状态的回调函数。
promise.then(
function (value) {
// success
},
function (error) {
// failure
}
);
then 方法可以接受两个回调函数作为参数。第一个回调函数是 Promise 对象的状态变为 Resolved 时调用,第二个回调函数是 Promise 对象的状态变为 Rejected 时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受 Promise 对象传出的值作为参数。
catch
promise.catch(
(error)=>{
//error
}
)
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。
链式操作
Promise 新建后就会立即执行。
let promise = new Promise(function (resolve, reject) {
console.log("Promise");
resolve();
});
promise.then(function () {
console.log("resolved.");
});
console.log("Hi!");
// Promise
// Hi!
// resolved.
上面代码中,Promise 新建后立即执行,所以首先输出的是“Promise”。然后,then 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以“resolved”最后输出。
应用
下面是一个使用 Promise 对象实现的 Ajax 操作的例子。
const getJSON = function (url) {
const promise = new Promise(function (resolve, reject) {
const handler = function () {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = handler;
xhr.responseType = "json";
xhr.setRequestHeader("Accept", "application/json");
xhr.send();
});
return promise;
};
getJSON("/posts.json").then(function (json) {});
上面代码中,getJSON 是对 XMLHttpRequest 对象的封装,用于发出一个针对 JSON 数据的 HTTP 请求,并且返回一个 Promise 对象。需要注意的是,在 getJSON 内部,resolve 函数和 reject 函数调用时,都带有参数。
如果调用 resolve 函数和 reject 函数时带有参数,那么它们的参数会被传递给回调函数。reject 函数的参数通常是 Error 对象的实例,表示抛出的错误。