异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大
异步是非阻塞的
Promise里的函数是同步调用的,异步操作在执行器中执行
var promise = new Promise(传一个函数)
var promise = new Promise(function (resolve, reject)) {
if(异步操作成功){
resolve(value)
} else {
reject(error)
}
}
Promise的状态
Promise的状态
实例对象中的一个属性 PromiseState
有三个状态:
1、pending 初始状态
2、pending = resolved/fullfilled 实现 操作成功
3、pending = rejected 拒绝 操作失败
tips:只会变为成功和失败两个状态,且一个promise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤
Promise对象的值
实例对象中的另一个属性 PromiseResult
保存的是异步任务失败/成功的结果
resolve
reject
Promise.resolve
如果传入的参数为非Promise对象,则返回的结果为成功promise对象
如果传入的参数为Promise对象,则参数的结果决定了resolve的结果
let p1 = Promise.resolve(521)
console.log(p1);
let p2 = Promise.resolve(new Promise(resolve, reject) => {
reject('Error')
})
p2.catch(err => {
console.log(err)
})
Promise.reject
无论传入什么参数,返回的结果都是失败
let p1 = Promise.reject(521)
console.log(p1);
promise.all
promise.all可以将多个promise实例包装成一个新的Promise实例,同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值
tips:要全部成功才返回一个成功结果的数组
碰到一个失败则直接返回第一个失败的结果
let p1 = new Promise(function(resolve, reject) {
resolve('success1')
})
let p2 = new Promise(function(resolve, reject) {
resolve('success2')
})
let p3 = Promise.reject('error')
Promise.all([p1, p2]).then(function(res){
console.log(res);
}).catch(err=>{
console.log(err);
})
Promise.all([p3, p1]).then(function(res){
console.log(res);
}).catch(err=>{
console.log(err);
})
Promise.all([p1, p3, p2]).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
Promise.race
顾名思义,Promise.race就是赛跑的意思,意思就是说,Promise.race([p1,p2,p3])里面哪个结果获得的快,就返回哪个结果,不管结果本身是成功状态还是失败状态
var promise1 = new Promise((resolve, reject)=> {
setTimeout(function(){
if(true){
resolve('success')
}else{
reject('lose')
}
},1000)
})
var promise2 = new Promise((resolve, reject)=>{
if(false){
resolve('success2')
}else{
reject('lose2')
}
})
Promise.race([promise1, promise2]).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
改变对象的三种方式
1、resolve函数
如果当前是pending就会变为resolved
2、reject函数
如果当前是pending就会变为rejected
3、抛出错误
如果当前是pending就会变为rejected
throw 'error'
一个promise指定多个成功/失败回调函数,都会调用吗?
只要状态发生改变则都会调用,状态没有改变则都不调用
let p1 = new Promise((resolve, reject)=>{
resolve('123')
})
p1.then(resolve => {
console.log(resolve);
})
p1.then(resolve => {
console.log(resolve);
})
Promise的链式调用
let p = new Promise((resolve, reject)=>{
resolve('123')
})
p.then(value => {
return new Promise((resolve, reject)=>{
resolve('success')
})
}).then(value => {
console.log(value);
}).then(value => {
console.log(value); //undefined 状态为成功,但是因为上面没有返回值 所以返回值为undefined
}).then(value => {
console.log(value); //undefined
})
promise异常穿透现象
用于then的链式调用,在最后放一个.catch就可以了
不管是哪一步发生失败,都交由最后的catch处理
let p = new Promise((resolve, reject)=>{
resolve('123')
})
p.then(value => {
return new Promise((resolve, reject)=>{
resolve('success')
})
}).then(value => {
console.log(value);
}).then(value => {
console.log(value);
throw '出错啦'
}).then(value => {
console.log(value);
}).catch(reason => {
console.log(reason);
})
中断promise链
有且只有一种方式,只有返回一个pending状态的promise对象
因为状态没有改变,所以后面的then执行不了
let p = new Promise((resolve, reject)=>{
resolve('123')
})
p.then(value => {
return new Promise((resolve, reject)=>{
resolve('success')
})
}).then(value => {
console.log(value);
}).then(value => {
return new Promise(()=>{})
}).then(value => {
console.log(value);
}).catch(reason => {
console.log(reason);
})
async和await
async是协同Promise工作的,放置在函数前面,返回一个Promise对象,关键词await可以让JavaScript进行等待,直到一个promise执行并返回它的结果,JavaScript才会继续往下执行,await只能在async定义的函数内部执行。
async声明异步函数
await会阻塞后面代码的执行
如果返回的是reject 则返回错误信息。后面代码不执行
async
async function main() {
// 如果返回值是一个非Promise类型的数据,那么返回的就是一个成功的Promise对象,并且你返回的值是什么,PromiseResoult的值就是什么
return 521;
// 如果返回的是一个Promise 的对象,根据Promise的返回结果来判断,如果是resolve就是成功的,如果是reject就是失败的、
return new Promise((resolve, reject)=>{
reject('error')
})
// 如果是抛出异常,则Pormise状态为失败,并且返回值就是抛出异常的值
throw 'error'
}
await
1、await右侧的表达式一般为Promise对象,但也可以是其他值
2、如果表达式是promise对象,await返回的是promise成功的值
3、如果表达式是其他值,直接将此值作为await的返回值
注意:
1、await必须写在async函数中,但async函数中可以没有await
2、如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
进程和线程
进程:就是在内存中正在运行的程序就叫一个进程 特点:在内存中独享一份空间
进程负责为程序的运行提供必备的环境(相当于工厂中的车间)
线程:一个应用程序是由多个线程组成,每一个线程之间是相互独立的
线程是计算机中最小的计算单位,负责执行进程中的程序
js是一个单线程 如果遇到耗时任务,而且同步,就会造成线程阻塞
/* 同步的代码 线程被阻塞了 */
console.log(1);
alert("http")
console.log(2)
/* 回调函数处理耗时操作 */
/* 异步 */
console.log(1)
setTimeout(()=>{
console.log("http")
},1000)
console.log(2)