Promise和async

137 阅读3分钟

执行顺序: 宏任务 => 微任务 event loop : 执行队列 先执行宏任务队列,再执行微任务队列,执行游览器UI渲染 循环执行 宏任务; setTimeOut setInterval 微任务:Promise.then 或者catch

console.log('start')
setTimeout(() => {
	console.log('time')
})
Promise.resolve().then(() => {
	console.log('resolve')
})
console.log('end')

执行结果 start => end => resolve => time


new Promise(() => { console.log('1') })
Promise 必须手动执行resolve或者rejected ,then或者.catch才有结果 否则状态始终	pending,里面的代码也同步函数,同步执行

Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
 	console.log('timer2')
	}, 0)
});
const timer1 = setTimeout(() => {
	console.log('timer1')
	Promise.resolve().then(() => {
		console.log('promise2')
	})
}, 0)
console.log('start');


出现.then 是一个微队列 setTime是一个完整的宏队列
宏1 打印start 
微1打印promise1 
宏2 打印 time1  
微2 打印 promise2  
宏3打印time2

宏任务队列执行完后,一定要先去执行当前环境下的微任务,每一个宏任务都是单独队列

const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
	resolve('success')
	}, 1000)
})
const promise2 = promise1.then(() => {
	throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
	console.log('promise1', promise1)
	console.log('promise2', promise2)
}, 2000)

若当前宏任务中,Promise没有返回值,则抛出pending状态,表示正在执行,

resolve(1)  resolve(2)  .then(res)=> log(res)  
res只能为1,且不能改变,Promise的状态只能改变一次

throw new error .catch(res => log(res)).then(res => log(res))
catch也会返回一个Promise函数,但再then的话没有返回值,打印出来是undefined

.then或者.catch中使用return 抛出的值默认包装为resolve内的参数
如果没有抛出错误,会跳过catch方法,继续执行 

const promise = Promise.resolve().then(() => {
	return promise;
})
promise.catch(console.err)
.then 或者.catch不能返回promise本身 会死循环

Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
.then .catch参数期望是函数,传入非函数则值透传,只能输出第一个函数抛出的值

.then里面有两个参数 第一个处理成功 第二个处理失败

Promise.resolve()
	.then(function success (res) {
		throw new Error('error!!!')
}, function fail1 (err) {
	console.log('fail1', err)
}).catch(function fail2 (err) {
	console.log('fail2', err)
})

.finally()方法不管Promise对象最后的状态如何都会执行
.finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道		  Promise最终的状态是resolved还是rejected的
它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常		的Promise对象。

在一个宏任务下的一个函数中,一次执行一个微任务

紧跟着await后面的语句相当于放到了new Promise中,下一行及之后的语句相当于放在		Promise.thenasync function fn () {
// return await 1234
// 等同于
	return 123
}
fn().then(res => console.log(res))

scriot start
async1 statt
async2
promise1
script end
async1 end
promise2
settime

一定要牢记 不管newpromise 还是async await,状态值没有改变吗,就是一个同步执行函数 一个函数下的微队列 一次只能执行一条

async function async1() {
	console.log("async1 start");
await async2();
	console.log("async1 end");
}

async function async2() {
	console.log("async2");
}

console.log("script start");

setTimeout(function() {
	console.log("setTimeout");
}, 0);

async1();

new Promise(function(resolve) {
	console.log("promise1");
resolve();
}).then(function() {
	console.log("promise2");
});
console.log('script end')



3
7
4
1
2
5
函数

遇到xxx().then 先执行xxx函数,再执行.then

const first = () => (new Promise((resolve, reject) => {
	console.log(3);
let p = new Promise((resolve, reject) => {
    console.log(7);
    setTimeout(() => {
        console.log(5);
        resolve(6);
        console.log(p)
    }, 0)
    resolve(1);
});
resolve(2);
p.then((arg) => {
    console.log(arg);
});
}));
first().then((arg) => {
	console.log(arg);
});
console.log(4);


script start
async1
promise1
async1 end
script end
1
async success
time2
time1

const async1 = async () => {
	console.log('async1');
setTimeout(() => {
	console.log('timer1')
}, 2000)
await new Promise(resolve => {
	console.log('promise1')
})
console.log('async1 end')
	return 'async1 success'
} 

要注意到 使用await等待的话,await身后函数的promise的状态不改变,一直处于执行状态中的话,就无法执行await后面的代码,也就不存在async函数的.then方法

const p1 = new Promise((resolve) => {
	setTimeout(() => {
		resolve('resolve3');
		console.log('timer1')
	}, 0)
resolve('resovle1');
resolve('resolve2');
}).then(res => {
	console.log(res)
	setTimeout(() => {
		console.log(p1)
	}, 1000)
}).finally(res => {
	console.log('finally', res)
})

finally优先于settmei执行,finally 无法结束后promise返回值,res为undefined,finnally的promise的返回值是不抛错的情况是上一个的promise返回值。


const  a= [1,2,3]
const result = arr.reduce(x,y => {new promise(r => settimeout(() -> r(log(x),1000)))},promise,resolve)

set(() => red(),1000,2000,3000)

const light = function(time, cb){
	return new promise(() => {
    	setiset((resolve) => {
        	cb()
            resolve
        } ,tiem)
    })
}

const step = function(){
promise.resolve().then(() => {
	return(light(1000,red))})
}.then.then.then(step())