Promise 的概念
Promise是对JavaScript异步编程的一种解决方案,由于传统异步编程的一大特点是不断的回调嵌套,使得代码难以维护。于是Promise使用一种链式调用去解决这个问题。
Promise的状态和特点
-
它具有三种状态:
pending 未完成 resolved 已完成(成功) rejected 已失败
一个Promise对象代表一个异步操作,可把Promise当作一个容器,里面放着异步函数。* Promise对象一旦创建,就会立即执行*。状态是由进行中转为已完成或转为已失败,状态一旦改变,则不会再变。
外界不能改变Promise自身的状态,状态由其异步操作的结果来决定。
Promise的延迟执行
由于Promise对象一旦创建就会执行,所以可以有一种方法让promise创建执行先不执行,等需要的时候再执行。 * 创建一个普通的function,让它return一个Promise对象,等需要执行这个Promise的时候调用这个普通function。*
let p1 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('hello promise')
}, 1000)
})
}
p1()
Promise的状态和结果
## resolve和reject出去的结果,可以让.then()方法获取得到,而then()方法里面也可以包含两个函数,第一个函数接收resolve的结果,第二函数接收reject的结果
。
// 写法一
[1, 2, 3, 4].map(
(value) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if ((value === 1) || (value === 3)) reject(`--失败了-- reject: ${value}`)
else {
resolve(`--成功了--resolve: ${value}`)
// console.log(`----resolve: ${value}`)
}
}, value * 1000) // value * 1000 是为了显示隔一秒显示一个状态
}).then((res) => {
console.log(res)
})
}
)
//写法二
[1, 2, 3, 4].map(
(value) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if ((value === 1) || (value === 3)) reject(value)
else {
resolve(value)
// console.log(`----resolve: ${value}`)
}
}, value * 1000) // value * 1000 是为了显示隔一秒显示一个状态
}).then((res) => {
console.log(`--成功了--resolve: ${res}`)
}), (err) => {
console.log(`--失败了-- reject: ${err}`)
}
}
)
// 运行结果:
(node:13220) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): --失败了-- reject: 1
--成功了--resolve: 2
(node:13220) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): --失败了-- reject: 3
--成功了--resolve: 4
Promise的方法
Promise.all()
这个方法用来包装多个Promise对象实例,组成一个新的Promise,状态由包裹在里面Promise的状态决定,如果里面所有Promise都resolve了,则它的状态就是resolve,如果里面只要有一个Promise reject掉,状态就会是reject。
Promise.race()
race方法跟all方法功能相似,但用它组成的新Promise对象的状态取决于包裹在里面的所有Promise对象中状态第一个改变的Promise状态。
Promise.resolve()
能把具有then方法的对象转换为Promise对象,然后立即执行then方法,用此方法后产生的Promise对象状态为resolve,其他值忽略。
let arr = [null, 0, 'hello',
{then: function () {
setTimeout(() => {
console.log('the first then')
}, 1000)
}},
{then: function () {
setTimeout(() => {
console.log('the second then')
}, 2000)
}}
]
arr.map((value) => {
return Promise.resolve(value)
})
Promise.reject()
跟resolve方法一样,能把具有then方法的对象转换为Promise对象,然后立即执行then方法,用此方法后产生的Promise对象状态为reject。
Promise.prototype.then()
.then()方法定义在Promise.prototype上,作用是添加Promise实例状态改变时的回到函数。then()里面包含两个参数,其中第一个参数可接收resolve和reject两种状态的结果,而第二个参数为可选,作为reject状态的回调函数,接收reject的结果。 (如上面代码写法一和写法二)
.then()采用链式调用,第一个回调函数若返回的是还是一个Promise对象,也就是还有异步操作,那么接在后面的回调函数会等该Promise对象状态发生改变之后才会被调用。
Promise.all(arr)
.then((result) => {
return 'hello promise'
}).then((res) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 4000)
})
}).then((res) => {
console.log('如果上一个then方法里面的promise不改变状态,则这个then方法不会执行到')
return new Promise((resolve, reject) => {
reject(new Error('出错了'))
})
}).catch((err) => {
console.log(`catch error ... ${err}`)
})
Promise.prototype.catch()
Promise的捕获异常
catch方法用于指定Promise执行过程中发生错误时的回调函数。