上节课遗留
.finally
.finally()方法不管Promise对象最后的状态如何都会执行
.finally()方法的回调函数不接收任何的参数,也就是你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected的
它最终返回的默认会是一个上一次的Promise对象值,不过抛出的是一个异常则返回R状态的Promise对象
它也是创建的一瞬间就会产生一个promise对象,也需要代码执行完毕之后确定状态。虽然状态有一部分取决于之前对象。
test = Promise.resolve().finally(()=>{console.log('1111111')})
console.log(test)
test = Promise.reject().finally(()=>{console.log('1111111')})
console.log(test)
test = Promise.resolve().finally(()=>{console.log('1111111');throw 111})
console.log(test)
function promise1 () {
let p = new Promise((resolve) => {
console.log('promise1');
resolve('1')
})
return p;
}
function promise2 () {
return new Promise((resolve, reject) => {
reject('error')
})
}
promise1()
.then(res => console.log(res))
.catch(err => console.log(err))
.finally(() => console.log('finally1'))
promise2()
.then(res => console.log(res))
.catch(err => console.log(err))
.finally(() => console.log('finally2'))
Promise中的all和race
通俗来说,.all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调。
.race()的作用也是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃。
// 我们都知道 new 一个 promise的时候,内容会同步执行的
const p1 = new Promise(r => console.log('立即打印'))
// 因此在大多数情况下为了控制它什么时候执行,我们可以用一个函数包裹着它,在需要它执行的时候,调用这个函数就可以了
function runP1 () {
const p1 = new Promise(r => console.log('立即打印'))
return p1
}
runP1()
function runAsync (x) {
const p = new Promise(r => setTimeout(() => r(x, console.log(x)), 1000))
return p
}
我们拆分理解一下这个函数,在这之前先看一下这种写法 new Promise((r)=>{r('11'), console.log('11111')})
function runAsync (x) {
const p = new Promise(function (r) {
setTimeout(
function () {
r(x, console.log(x))
}
, 1000)
})
return p
}
那如果用 .all执行会怎么样
function runAsync (x) {
console.log('ready', x)
const p = new Promise(r => setTimeout(() => r(x, console.log(x)), x*1000))
return p
}
Promise.all([runAsync(3), runAsync(2), runAsync(1)])
.then(res => console.log(res))
console.log('start')
.all方法中只能传入可迭代
Promise.all 接受的必须是一个可迭代的对象
.then()里的回调函数接收的就是所有异步操作的结果。
而且这个结果中数组的顺序和Promise.all()接收到的数组顺序一致
.then 的状态取决于之前 .all 全部的状态
一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。
使用.race()方法,它只会获取最先执行完成的那个结果,其它的异步任务虽然也会继续进行下去,不过race已经不管那些任务的结果了
function runAsync (x) {
console.log('ready', x)
const p = new Promise(r => setTimeout(() => r(x, console.log(x)), x*1000))
return p
}
Promise.race([runAsync(3), runAsync(2), runAsync(1)])
.then(res => console.log(res))
console.log('start')
async(异步关键字) 与 await
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
async1();
console.log('start')
首先一进来是创建了两个函数的,我们先不看函数的创建位置,而是看它的调用位置
发现async1函数被调用了,然后去看看调用的内容
执行函数中的同步代码async1 start,之后碰到了await,它会阻塞async1后面代码的执行,因此会先去执行async2中的同步代码async2,然后跳出async1
跳出async1函数后,执行同步代码start
在一轮宏任务全部执行完之后,再来执行刚刚await后面的内容async1 end
// 正常情况下,async中的await命令是一个Promise对象,返回该对象的结果。
//
// 但如果不是Promise对象的话,就会直接返回对应的值,相当于Promise.resolve()
async function fn () {
// return await 123
// 等同于
return 123
}
fn().then(res => console.log(res))
async function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing();
console.log(v1);
const v2 = await testAsync();
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise(resolve => {
console.log("promise start...");
resolve("promise");
});
promise.then(val => console.log(val));
console.log("test end...");
所以说 Promise.resolve("hello async"); 和 return "testSometing" 效果是一样滴~
// 在async中,如果 await后面的内容是一个异常或者错误的话,简单看一下
// 如果在async函数中抛出了错误,则终止错误结果,不会继续向下执行。
async function async1 () {
await async2();
console.log('async1');
return 'async1 success'
}
async function async2 () {
return new Promise((resolve, reject) => {
console.log('async2')
reject('error')
})
}
async1().then(res => console.log(res))
// 如果想要使得错误的地方不影响async函数后续的执行的话,就要使用try catch了
async function async1 () {
try {
await Promise.reject('error!!!')
} catch(e) {
console.log(e)
}
console.log('async1');
return Promise.resolve('async1 success')
}
async1().then(res => console.log(res))
console.log('script start')