async/await/promise/ setTimeout/ event loop

promise:
[cc lang=”javascript”]
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error(‘fail’)), 3000)
})

const p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000)
})

p2
.then(result => console.log(result))
.catch(error => console.log(error))
// Error: fail
[/cc]
上面代码中,p1是一个 Promise,3 秒之后变为rejected。p2的状态在 1 秒之后改变,resolve方法返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。

!!! 注意,调用resolve或reject并不会终结 Promise 的参数函数的执行。如下
[cc lang=”js”]
new Promise((resolve, reject) => {
resolve(1); //这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
如果加上return语句就不会打印2
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
[/cc]
promise then 方法
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
then里的 回调函数完成以后,会将返回结果作为参数,传入下一次回调函数。如果回调函数返回promise,这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用
promise catch 方法
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数.
建议用catch 不要用then 第二个方法
!!! catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法

promise.all([ p1, p2, p3 ]).then().catch

promise.race([ p1, p2, p3]).then().catch
那个率先改变的 Promise 实例的返回值,就传递给then或catch的回调函数
[cc lang=”js”]
const p = Promise.race([
fetch(‘/resource-that-may-take-a-while’),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error(‘request timeout’)), 5000)
})
]);

p
.then(console.log)
.catch(console.error);
//上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数

[/cc]

1.async 函数返回的是一个 Promise 对象,async 函数没有返回值,它会返回 Promise.resolve(undefined)

2 await 如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await就忙起来了,它会阻塞asycn函数内后面的代码,等着Promise对象resolve,然后得到 resolve 的值,作为 await 表达式的运算结果
3。1 js 执行机制 event loop
首先判断JS是同步还是异步,同步就进入主进程,异步就进入event table
异步任务在event table中注册函数,当满足触发条件后,被推入event queue
同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中
3.2event loop (2)
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick

!! 执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的【事件队列】里
当前宏任务执行完成后,会查看微任务的【事件队列】,并将里面全部的微任务依次执行完
[cc lang=”javascript”]
async function async1() {
console.log( ‘async1 start’ )
await async2() // return promise 此时返回的Promise会被放入到回调队列中等待,await会让出线程
//等外面执行完成后再回到这生成promise.resolve(undefined) 又被放到micro-task, 再次让出线程跳出async
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 会放入micro-task 让出线程
console.log(34)
} ).then( function () {
console.log( ‘promise2’ )
return Promise.resolve();
} ).then(function(){console.log(11)
return Promise.resolve();
}).then(function(){console.log(22)})

console.log( ‘script end’ )

//script start
//async1 start
//async2
//promise1
// 34
//script end
//promise2
//async1 end
//11
//22
// setTimeout
[/cc]

Leave a Reply

Your email address will not be published. Required fields are marked *