1、简述ES6中的Promise对象
答:① Promise是一个构造函数,可以通过 new 关键字进行创建实例 ② Promise是异步编程的一种解决方案。 ③ Promise就像一个容器,里面存在着未来才会结束的事情结果。
2、Promise的特点
答:① Promise对象的状态不受外界的干扰,只有异步操作的结果才能决定最终的状态 ② Promise的状态一旦改变,就不会再进行变化。
3、Promise有哪些状态及状态流转
答:① 有3种状态,有2种状态流转 ② 三种状态分别是,pending(进行中)状态、fulfilled(已成功)状态、rejected(已失败)状态 ③ 两种状态流转分别是,pending 变为 fulfilled状态、pending 变为 rejected状态
4、Promise的缺点
答:① 一旦建立Promise实例就会立即执行,中途不能取消; ② 如果不设置回调函数(then方法绑定的函数),Promise内部抛出的错误是没办法抛到外部; ③ 当状态在pending时,没有办法得知状态是刚刚开始还是即将完成。
5、怎么使用Promise对象
答:① 使用new关键字创建Promise的实例 ② Promise构造函数接受一个函数作为参数,该函数的两个参数是resolve 和reject ③ 参数resolve和reject是函数,由JS引擎提供不用自己去部署 ④ resolve函数的作用是将状态从pending变为fulfilled ⑤ reject函数的作用是将状态从pending变为rejected ⑥ 异步操作的结果或者错误可以通过 resolve 和 reject函数传递出去 ⑦ Promise实例一经创建便执行,Pomise实例的then中的回调函数要等脚本的所有同步操作执行完才执行 ⑧ resolve和reject不会中止Promise里代码的执行 ⑨ 建议resolve和reject函数后面的代码放入Promise的then回调函数中,代码更加清晰美观 ⑩ Promise的then回调可以有多个,后一个回调的参数是前一个回调的结果
let p = new Promise((resolve, reject) => {
console.log('Promise')
let a = 1;
if(a === 1){
resolve('a等于1')
console.log('resolve is over')
}else{
reject('a不等于1')
console.log('reject is over')
}
})
p.then(res => {
console.log(res)
return '第一个then回调的结果'
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
console.log(2222)
6、简述Promise.prototype.then(resFun, errFun)方法
答:① Promise.prototype.then() 方法是 Promise 状态从 pending 变为 resolved 的回调; ② Promise可以有多个 then 回调,第一个 then 回调函数的参数,是 resolve 抛出来的,后面的then回调参数是前一个then回调函数return的结果。 ③ 参数resFun是成功的回调函数,errFun是失败的回调(即catch方法),一般不建议catch方法用then的第二参数表示。
promise.then(function(data) {
}, function(err) {
});
promise.then(function(data) {
}).catch(function(err) {
});
7、简述 Promise.prototype.catch() 方法
答:① Promise.prototype.catch() 方法是 Promise 状态从 pending 变为 rejected 的回调,用来捕捉发生的错误。 ② Promise.prototype.catch() 是Promise.prototype.then(null, rejection)的别名。 ③ Promise可以有多个 catch 回调,第一个 catch 回调的参数,是前面代码运行时抛出的错误,后面的 catch 回调参数则是前一个catch方法抛出的错误。 ④ Promise 的 catch 返回的还是一个 Promise 对象,所以后面可以继续接着调用 catch 或者 then 方法。 ⑤ Promise 的 catch 执行完后,如果后面还有 catch 或者 then 方法,会继续进行代码的执行。 ⑥ 如果代码没有出错误,那么会跳过catch 方法,继续向后执行代码。 ⑦ 如果代码出了错误,但是没有 catch 方法,那么错误不会抛到外层去。 ⑧ 如果代码出了错误,那么这个错误是有‘冒泡’的性质,一直会往后传递,知道被catch捕捉到为止。 ⑨ 在浏览器中,Promise内部出了错误,不会影响到Promise的外部代码,浏览器会打印错误提示,代码依然继续执行。 ⑩ 在Node.js中,Promise内部出了错误,会有一个unhandledRejection事件专门监听未捕捉的rejection错误,此时中止进程且进程的退出码不为0。 ⑩ 如果 Promise 的状态已经变成 resolved,在用 throw 抛出错误是无效的。
let p = new Promise((resolve, reject) => {
let a = 1
if(a > 1){
resolve()
}else{
reject('error')
throw new Error('error')
}
})
p.then(res1 => {
return 'res1的结果'
}).then(res2 => {
a = y
return 'res2的结果'
}).catch(err1 => {
console.log(111)
console.log(err1)
console.log(11111111111)
return 'err1'
}).then(res3 => {
a = dd
console.log(222)
console.log(res3)
console.log(221)
return 'res3'
}).catch(err2 => {
console.log(3333)
console.log(err2)
console.log(331)
y= www
return 'err2'
}).catch(err3 => {
console.log(444)
console.log(err3)
console.log(441)
return 'err3'
})
8、简述Promise.prototype.finally()方法
答:① 这个方法不管在Promise的fulfilled状态还是rejected状态,最后都会进行执行调用。 ② 这个回调函数不接受任何的参数,不依赖于Promise的执行结果。本质上是then方法的特例。 ③ finally方法总是会返回原来的值。
Promise.prototype.finally = function(callback){
let p = this.constructor;
return this.then(
res = > p.resolve(callback()).then(() => res),
err => p.resolve(callback()).then(() => {throw err})
)
}
promise.then((res) => {}).catch((err) => {}).finally(() => {})
promise.then(
res => { return res;},
error => { throw error; }
);
Promise.resolve(2).then(() => {}, () => {})
Promise.resolve(2).finally(() => {})
Promise.reject(3).then(() => {}, () => {})
Promise.reject(3).finally(() => {})
9、简述Promise.all()方法
答:① 该方法时将多个Promise实例,包装成一个新的Promise实例。 ② 该方法的参数可以是数组,也可以是具有Iterator接口的对象。 ③ Promise.all()方法中参数中的成员需要是Promise实例,如果不是,会自动使用Promise.resolve方法转换。
let p1 = new Promise(), p2 = new Promise, p3 = new Promise()
p1.then((res) => {});
p2.then((res) => {});
p3.then((res) => {});
let pAll = Promise.all([p1, p2, p3])
10、Promise.all()方法的状态是什么呢?
答:① 它的状态由传入参数成员的状态来决定。 ② 如果成员的状态都是 fulfilled,那么 Promise.all()的状态就会变成 fulfilled。 ③ 如果成员的状态有一个是rejected,Promise.all()的状态就是rejected,
let p1 = new Promise(), p2 = new Promise, p3 = new Promise()
p1.then((res) => {});
p2.then((res) => {});
p3.then((res) => {});
let pAll = Promise.all([p1, p2, p3])
11、Promise.all()方法的回调函数的参数是什么呢?
答:① 如果Promise.all方法的参数成员状态都是resolved,此时Promise.all 的返回值就是所有成员返回值组成的数组,并传给Promise.all的回调函数。 ② 如果Promise.all方法的参数成员状态有一个是rejected,那么第一个rejected的成员的返回值就是Promise.all回调函数的参数。
let p1 = new Promise(), p2 = new Promise, p3 = new Promise()
p1.then((res) => {});
p2.then((res) => {});
p3.then((res) => {});
let pAll = Promise.all([p1, p2, p3])
pAll.then(res => {
})
12、Promise.all()方法中参数成员本身rejected对Promise.all()方法catch的影响是什么?
答:① 如果参数成员本身定义了catch方法,那么被rejected时并不会触发Promise.all()的catch方法 ② 如果参数成员本身没有定义catch方法,那么被rejected时会触发Promise.all()的catch()方法
const p1 = new Promise((resolve, reject) => {
resolve('hello');
}).then(result => result).catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
}).then(result => result).catch(e => e);
const p3 = new Promise((resolve, reject) => {
resolve('hello');
}).then(result => result);
const p4 = new Promise((resolve, reject) => {
throw new Error('报错了');
}).then(result => result);
Promise.all([p1, p2]).then(
result => console.log(result)
).catch(
e => console.log(e)
);
Promise.all([p3, p4]).then(
result => console.log(result)
).catch(
e => console.log(e)
);
13、简述Promise.race([成员1, 成员2…])方法
答:① 和Promise.all()方法的功能相同,都是将多个Promise实例包装成一个新的Promise实例 ② 如果传入的参数成员不是Promise实例,那么会使用Promise.resolve转换一下。 ③ 只要参数成员中有一个成员的状态率先发生了改变,那么Promise.race()的状态就跟着改变, ④ Promise.race()的返回值是第一个状态发生改变的参数成员的返回值。 const p = Promise.race([p1, p2, p3]) // 只要三个成员中有一个率先改变状态,p的状态就跟着改变
14、简述 Promise.allSettled()方法
答:① Promise.all()方法需要成员的状态都是resolved,只要有一个成员失败了,Promise.all()就会失败,无法进行下一步操作。 ② Promise.allSettled()方法就是为了解决这个问题,也是接受一个由Promise实例组成的数组,只要参数数组成员的操作都结束(不管成功还是失败),Promise.allSettled()状态都是fulfilled,会进行下一步操作。 ③ Promise.allSellted()方法的回调函数(then)的结果是一个数组对象,数组对象的格式固定,只有两种格式。
const resolved = Promise.resolve(42)
const rejected = Promise.reject(-1)
const allSettled = Promise.allSettled(resolved, rejected)
allSettled.then((res) => {
console.log(res)
})
const suc = allSettled.filter(p => p.status === 'fulfilled');
const err = allSettled.filter(p => p.status === 'rejected').map(p => p.reason);
15、简述Promise.any()方法
答:① 该方法参数是一个数组,数组里面的成员是Promise实例。 ② 当数组成员的所有成员的状态有一个是fulfilled,Promise.any()方法状态就是fulfilled状态 ③ 当数组成员的所欲成员状态都是rejected,Promise.any()方法状态就是rejected状态
Promise.any([
fetch('https://v8.dev/').then(() => 'home'),
fetch('https://v8.dev/blog').then(() => 'blog'),
fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {
console.log(first);
}).catch((error) => {
console.log(error);
});
16、Promise.race()、Promise.any()、Promise.all()和Promise.allSettled()方法的区别
答:① 它们的参数都是数组,数组的成员都是Promise实例,如果不是,会自动使用Promise.resolve进行转换 ② 它们最后的返回值都是一个新的Promise实例 ③ Promise.race()的状态由第一个率先改变状态的数组成员决定,如果这个成员状态是rejected那么最后状态就是rejected,反之为fulfilled状态。 ④ Promise.race()回调函数的入参是第一率先改变状态的成员返回值。 ⑤ Promise.any()的状态由数组成员状态决定,全部成员状态为rejected,最后结果状态是rejected,有一个成员状态是fulfilled,最后结果是fulfilled ⑥ Promise.any()中,如果有一个成员状态是rejected,那么Promise.all()的回调函数的入参是被reject的返回值组成的数组,如果成员状态有一个是fulfilled,那么入参是参数成员返回值 ⑦ Promise.all()方法中,如果参数成员有一个成员状态变为rejected,那么最后状态就会变成rejected,只有全部成员状态是fulfilled,最后状态才是fulfilled。 ⑧ Promise.all()方法中,如果有一个成员状态是rejected,那么Promise.all()的回调函数catch的入参是第一个被reject的返回值,如果成员状态都是fulfilled,那么入参是参数成员返回值组成的数组。 ⑨ Promise.allSettled()方法中,最后状态都是fulfilled ⑩ Promise.allSetteld()方法,回调函数接受一个数组对象作为入参,每个对象是对应成员的返回值,只有两种格式,格式如下: {status: ‘fulfilled’, value: value} // 异步操作成功时 {status: ‘rejected’, reason: reason} // 异步操作失败时
17、简述Promise.resolve()方法
答:① 这个方法用于将一个对象转换成Promise对象 ② Promise.resolve(xxx)等价于 new Promise(resolve => resolve(xxx)) ③ Promise.resolve是在本轮事件循环结束时执行
setTimeout(function(){
console.log('111')
}, 0)
Promise.resolve().then(() => {
console.log(222)
})
console.log(333)
18、简述Promise.resolve(x)方法的对不同参数类型的处理
答:① 当参数 x 为 Promise 实例,那么不对其做任何处理,直接返回 ② 当参数 x 是一个 thenable 对象(具有then方法的对象),会将其先转为 Promise 对象,然后立即执行 thenable里面的then方法。 ③ 当参数 x 是一个普通对象或者原始值,会返回一个新的 Promise 对象 ④ 当没有参数的时候,会直接返回一个 resolved 状态的 Promise 对象
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function (value) {
console.log(value);
});
19、简述Promise.reject()方法
答:① 该方法也会返回一个Promise实例,状态为rejected。 ② 该方法会将入参作为回调函数catch的参数 ③ 该方法等同于 new Promise((resolve, reject) => reject())
var p = Promise.reject(111)
p.catch(err => {
console.log(err)
})
20、Promise对象的应用有哪些
答:① 图片的加载 ② 与Generator函数的结合
21、Promise.try()方法
答:该方法模拟try代码块,用来捕获所有的同步和异步错误。
Promise.try(() => {
}).then(...).catch(...);
22、让同步函数同步执行,异步函数异步执行,并让它们具有统一API的办法有哪些
答:① 匿名函数立即执行+async方法, (async () => fun())().then(…).catch(…) ② 匿名函数立即执行 + new Promise方法, (() => new Promise(resolve => resolve(fun())))() ③ 通过Promise.try方法,Promise.try(() => fun()).then(…).catch(…)
23、Promise的finally回调
答:这个回调是不管Promise在哪种状态(fulfilled还是rejected)都会执行的回调, 它的入参是一个函数,不管怎么样,这个函数都会执行。
let p = new Promise((resolve, reject) => {resolve(111)})
p.then(
res => console.log(res)
).catch(
err => console.log(err)
).finally(
() => console.log(2222)
)
24、Promise的done回调
答:这个方法总是处于回调链的尾端,可以捕捉到抛出的任何错误。
new Promise().then().then().catch().then().catch().then().done()
|