引入
要学好Promise,首先要理解学会回调函数和异步编程的思想。
1、同步就是js代码按照从上到下的顺序执行,只有上一步的代码执行完毕后才会执行下一步的代码。比如:
function createData() {
// 生成一个5-10之间的随机整数
var num = parseInt(Math.random()*(10-5)+5)
return num
}
var obj = {
name:"xiaozhang",
data:10,
tool:function() {
var data = createData()
this.data = data
}
}
obj.tool()
console.log(obj.data);
2、异步 和同步是相对的,它执行的顺序不再是按照代码书写的顺序来执行,比如说回调函数就是一个异步执行过程。
function createData(callback) {
var num = parseInt(Math.random()*(10-5)+5)
callback(num)
}
var obj = {
name:"xiaozhang",
data:10,
tool:function() {
createData((n) => {
this.data = n
})
}
}
obj.tool()
console.log(obj.data);
3、但是异步函数中又分为了阻塞异步函数和非阻塞异步函数两种。
(1)阻塞异步函数:就是一个业务代码在子线程上执行时,其他的代码不能执行,需要等待当前的执行完毕之后。
function fn(callback,n) {
for (let i = 0; i < n; i++) {
//循环n次
}
callback(n)
}
console.log("hello");
// 异步阻塞函数
fn(function () {console.log("aaa");},1000)
console.log("xiaozhang"); //需要上一步执行完毕,才执行
(2)非阻塞异步函数: 和阻塞异步函数相对,它的业务代码在子线程上执行时,不会影响后面代码的执行,可以同时开始执行。基本上非阻塞异步函数都是官方提供的函数方法。
function fn(callback,n) {
for (let i = 0; i < n; i++) {
//循环n次
}
callback(n)
}
console.log("hello");
// 非阻塞异步函数
setTimeout(function() {console.log("aaa");},1000)
console.log("xiaozhang");
常见的非阻塞异步函数,有:
setTimeout()函数是一个非阻塞的异步函数。
后端的fs.readFile()函数也是一个非阻塞的异步函数。
ES6中的Promise对象的then函数也是一个非阻塞的异步函数。
Promise概念
有了以上两种设计思想之后,我们就可以正式进入Promise对象的学习了。
概念:
-
promise是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
-
Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
-
Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。
-
Promise是一个构造函数,其原型上有then、catch方法,对象上有reject、resolve方法。
Promise与数组、对象、Map对象和Set对象的区别:
数组、对象、Map对象和Set对象与Promise虽然都是一个构造函数,都是数据容器,但是Promise是它自己主动产生数据,不用给它添加数据;而Array、Object、Map、Set都是由我们给它被动的添加数据。
Promise语法
1)通过new关键字创建Promise对象
var p1 = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('xiaozhang');
resolve('hello');
}, 1000);
})
参数说明:
-
resolve:异步操作执行成功后的回调函数
-
reject:异步操作执行失败后的回调函数
resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。
2)then方法
(1)创建的Promise对象通过调用then方法来取出数据。
(2)then函数的返回值 是一个新的Promise对象,是then传入的回调函数的返回值:
1.如果返回值是一个Promise对象 那么就是返回值。
2.如果返回值不是一个Promise对象,那么就会把函数的结果包装为一个生成数据了的Promise对象。
var p1 = new Promise(function (resolve, reject) {
var n = Math.random()
resolve(n)
})
p1.then(function(num) {
console.log(num);
})
3) catch方法
当Promise对象产生了错误的业务数据,调用了reject回调函数之后,用catch方法来捕获错误异常信息。
如果不使用catch捕获异常信息时,程序就会报错,影响后续业务的执行:
var p1 = new Promise(function (resolve, reject) {
var n = Math.random()
if (n > 0.5) {
resolve(n)
}else {
reject(n)
}
})
p1.then((num) => {
console.log(num);
})
使用catch捕获错误异常信息之后就会继续正常执行:
var p1 = new Promise(function (resolve, reject) {
var n = Math.random()
if (n > 0.5) {
resolve(n)
}else {
reject(n)
}
})
p1.then((num) => {
console.log(num);
}).catch((err) => {
console.log(err);
})