JavaScript异步编程之Promise
基本概念
Promise 是一个对象,从它可以获取异步操作的消息。
Promise 不需要去订阅一个事件,也不需要传递一个回调函数,而是通过自身状态的改变来通知目标函数。
Promise 对象的状态有以下三个特点:
1、Promise 对象有三种状态:pending(进行中)、resolved(已成功)和rejected(已失败)。
2、Promise 对象的状态改变只有两种可能:从 pending 变为 resolved 和从 pending 变为 rejected。
3、只有当 Promise 对象的状态改变时,才能通过 then() 方法采取特定的行动。
例子:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
//1秒钟之后:状态从 pending 变为 resolved
resolve("ok");
}, 1000)
});
//状态改变,then()方法的回调函数加入队列中等待执行
//参数(data)的值为 resolve 方法的参数,可任意类型
promise.then((data) => {
console.log(data);
});
//输出:ok
基本用法
Promise 是一个构造函数,使用 new 来生成 Promise 实例对象。
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject :resolve 函数的作用是,将 Promise 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在操作成功时调用;reject 函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在操作失败时调用。
Promise 实例对象生成以后,可以用 then() 方法分别指定 resolved 状态和 rejected 状态的回调函数。
例子:
let n = Math.floor(Math.random() * 10 + 1);
const promise = new Promise((resolve, reject) => {
if (n % 2 === 0) {
//如果数值为偶数,则变为成功状态
resolve("偶数");
console.log(n);
} else {
//如果数值为奇数,则变为失败状态
reject("奇数");
console.log(n);
}
});
promise.then(
//成功状态下的处理函数
data => {
console.log(data);
},
//失败状态下的处理函数
data => {
console.log(data);
});
通过上面的例子可以发现:
1、then() 方法可以接受两个回调函数作为参数。第一个回调函数是 Promise 对象的状态变为 resolved 时调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用。其中,第二个函数是可选的,不一定要提供。
例子:
const promise = new Promise((resolve) => {
resolve("ok");
});
promise.then(
data => {
console.log(data);
});
//输出:ok
也可以使用 then(null, rejection) 的形式只去指定状态为 rejected 时的回调函数。
例子:
const promise = new Promise((resolve, reject) => {
reject("no");
})
promise.then(
null,
(data) => {
console.log(data);
});
//输出:no
2、如果调用 resolve 函数和 reject 函数时带有参数,那么它们的参数会被传递给回调函数。
3、调用 resolve 或 reject 并不会终结 Promise 的执行。
Promise 对象的方法
Promise.prototype.then() 方法
then() 的基本用法上面已经介绍过,then() 方法还有一个特点:该方法可以采用链式写法,即 then() 方法后面再调用另一个 then() 方法。
例子:
const promise = new Promise((resolve, reject) => {
resolve(1);
})
promise.then((data) => {
console.log(data);
//返回的数据会作为后一个 then()方法的参数
return data + 1;
}).then((data) => {
console.log(data);
return data + 1;
}).then((data) => {
console.log(data);
});
//输出:1 2 3
如果前一个 then() 方法返回的还是一个Promise对象,这时后一个then() 方法,就会等待该 Promise 对象的状态发生变化,才会被调用。
例子:
let p1 = () => {
return new Promise((resolve, reject) => {
resolve(1);
});
};
let p2 = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, time)
})
};
p1().then((data) => {
console.log(data);
return p2(2000);
}).then((data) => {
console.log(data);
});
//输出:1 2
Promise.prototype.catch() 方法
Promise.prototype.finally() 方法
catch() 方法是 then(null, rejection) 的别名,用于指定发生错误时的回调函数。
finally() 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
例子:
let n = Math.floor(Math.random() * 5 + 0);
let arr = [1, "A", "B", 2, 3];
console.log(arr[n]);
const promise = new Promise((resolve, reject) => {
if (typeof(arr[n]) === "number") {
setTimeout(() => {
resolve("数值");
}, 3000)
} else {
setTimeout(() => {
reject("文本");
}, 3000)
}
})
promise.then(
data => {
console.log(data);
}).catch(
data => {
console.log(data);
}).finally(
() => {
console.log("end");
});
Promise.all() 方法
Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。Promise.all() 方法接受一个数组(类数组也可以)作为参数,参数都是 Promise 实例。
下面例子中的 Promise 对象的状态由p1、p2决定,分成两种情况:
1、只有p1、p2的状态都变成 resolved,p 的状态才会变成 resolved,此时p1、p2的返回值组成一个数组,传递给p 的回调函数。
例子:
const p1 = new Promise((resolve, reject) => {
resolve(1);
});
const p2 = new Promise((resolve, reject) => {
resolve(2);
});
const p = Promise.all([p1, p2]);
p.then((data) => {
console.log(data);
}).catch((data) => {
console.log(data);
});
//输出:[1, 2]
2、只要p1、p2之中有一个被 rejected,p 的状态就变成 rejected,此时第一个被 reject 的实例的返回值,会传递给p 的回调函数。
例子:
const p1 = new Promise((resolve, reject) => {
resolve(1);
});
const p2 = new Promise((resolve, reject) => {
reject(2);
});
const p = Promise.all([p1, p2]);
p.then((data) => {
console.log(data);
}).catch((data) => {
console.log(data);
});
//输出:2
Promise.race()方法
Promise.race() 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
下面例子中,只要p1、p2之中有一个实例率先改变状态,p 的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p 的回调函数。
例子:
let p1 = time => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, time);
})
};
let p2 = time => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(2);
}, time);
})
};
const p = Promise.race([p1(100), p2(200)]);
p.then(data => {
console.log(data);
}).catch((data) => {
console.log(data);
});
//输出:1
Promise.resolve() 方法
Promise.reject() 方法
Promise.resolve() 方法将现有对象转为 Promise 对象,状态为 resolved。
Promise.reject() 方法将现有对象转为 Promise 对象,状态为 rejected。
例子:
Promise.resolve().then(() => console.log("ok")); //输出:ok
Promise.reject().catch(() => console.log("no")); //输出:no
Promise.resolve("ok").then(data => console.log(data)); //输出:ok
Promise.reject("no").catch(data => console.log(data)); //输出:no
如有错误,欢迎指正,本人不胜感激。
共同学习,写下你的评论
评论加载中...
作者其他优质文章