Promise的几道基础题
const promise1 = new Promise((resolve, reject) => {
console.log('promise1')
})
console.log('1', promise1);
1.new 的时候就已经开始执行
如果出现下面这种被
const fn = () => (new Promise((resolve, reject) => {
console.log(1);
resolve('success')
}))
fn().then(res => {
console.log(res)
})
console.log('start')
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve('success')
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
resolve('success')这一步会把状态改成fulfilled,并把success这个值保存下来,如何继续执行同步任务,then后面是微任务
const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
3.如果Promise没有resolve或者reject时,promise.then()里面的代码不会被执行,它只有在状态被改变之后才会执行!
new Promise((resolve, reject) => {
return resolve(1);
console.log(2);
})
4.当出现resolve一个数值或者没有then的时候会返回一个promise对象并把resolve里面的参数传递过去
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
Promise.resolve(1)
.then(function(){return 2})
.then(Promise.resolve(3))
.then(console.log)
Promise.resolve(1)
.then(function(){return 2})
.then(function(){return Promise.resolve(3)})
.then(console.log)
5. .then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。Promise方法链通过return传值,没有return就只是相互独立的任务而已
const promise1 = new Promise((resolve, reject) => {
console.log('promise1')
resolve('resolve1')
})
const promise2 = promise1.then(res => {
console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);
6.new执行打印出promise1,resolve('resolve1')改状态,保存值,then为微任务,再继续执行同步代码和then
Promise结合setTimeout
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
7.定时器是宏任务在微任务之后执行,timerStart timerEnd为定时器里面的同步代码,resolve("success")保存值,then微任务
例1:
setTimeout(() => {
console.log('timer1');
setTimeout(() => {
console.log('timer3')
}, 0)
}, 0)
setTimeout(() => {
console.log('timer2')
}, 0)
console.log('start')
例2:
setTimeout(() => {
console.log('timer1');
Promise.resolve().then(() => {
console.log('promise')
})
}, 0)
setTimeout(() => {
console.log('timer2')
}, 0)
console.log('start')
8.两者一个是定时器,一个是Pomise.then ;可以理解为定时器是宏任务会被加入到下一轮宏仁务中,Pomise.then是微任务会被加入到本轮的微任务中
Promise中的then、catch、finally
const promise = new Promise((resolve, reject) => {
resolve("success1");
reject("error");
resolve("success2");
});
promise
.then(res => {
console.log("then: ", res);
}).catch(err => {
console.log("catch: ", err);
})
9.构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用 。Promise的状态一经改变就不能再改变
const promise = new Promise((resolve, reject) => {
reject("error");
resolve("success2");
});
promise
.then(res => {
console.log("then1: ", res);
}).then(res => {
console.log("then2: ", res);
}).catch(err => {
console.log("catch: ", err);
}).then(res => {
console.log("then3: ", res);
})
10.如9所述,当前Promise状态被改成rejected,后面的resolve不会再执行,所以可以得到catch:error;至于会打印出then3: undefined是因为.then和.catch都会返回一个新的Promise,且由于这个Promise没有返回值,所以打印出来的是undefined
Promise.resolve(1)
.then(res => {
console.log(res);
return 2;
})
.catch(err => {
console.log(err);
return 3;
})
.then(res => {
console.log(res);
});
11.在Promise中,返回任意一个非 promise 的值都会被包裹成 promise 对象,例如return 2会被包装为return Promise.resolve(2);且Promise可以链式调用,resolve(1)走的是第一个then,resolve(2)走的是第二个then
改成Promise.reject(1)也一样,上题会打印出1和3 ,return 3还是会包装成return Promise.resolve(3)
Promise.resolve().then(() => {
return new Error('error!!!')
}).then(res => {
console.log("then: ", res)
}).catch(err => {
console.log("catch: ", err)
})
如果想抛出错误的话可以使用:
return Promise.reject(new Error('error'))或者throw new Error('error')
const promise = Promise.resolve().then(() => {
return promise;
})
promise.catch(console.err)
12..then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环
Promise.reject('err!!!')
.then((res) => {
console.log('success', res)
}, (err) => {
console.log('error', err)
}).catch(err => {
console.log('catch', err)
})
13.then有两个参数分别处理成功Promise.resolve()和失败的函数Promise.reject,现在是进入到then的第二个参数里面,这时代码不会执行,去掉第二个参数的话会进入到catch里面
还有另外一种情况:
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)
})
因为调用的是resolve()所以会进入到success函数,不会进入到fail1,这时success函数抛出了一个错误会被catch捕获到
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'))
14. promise1()执行完同步代码打印出promise1,resolve('1')改状态存值;
then微任务1;
finally()得等then执行完才会执行;
执行promise2(),没有同步任务,catch微任务2,finally()得等catch执行完才会执行
async/await的几道题
async function async1 () {
console.log('async1 start');
await new Promise(resolve => {
console.log('promise1')
})
console.log('async1 success');
return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')
15. await后面的promise没有返回值没有改变状态,一直在pending中,
所以一直await使得后面的代码不会被执行,同样then后面也不会执行
async function async1 () {
console.log('async1 start');
await new Promise(resolve => {
console.log('promise1')
resolve('promise1 resolve')
}).then(res => console.log(res))
console.log('async1 success');
return 'async1 end'
}
console.log('srcipt start')
async1().then(res => console.log(res))
console.log('srcipt end')
async1 start
promise1
srcipt end
promise1 resolve
async1 success
async1 end
16.console.log('async1 success')被放在await语法糖生成的Promise.then里了,
而await的等待必须要等后面Promise.then之后才会结束.
在async1中的new Promise它的resovle的值和async1().then()里的值是没有关系的.
async 函数会返回一个 Promise 对象,如果在函数中 return 一个直接量(普通变量),
async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。
如果你返回了promise那就以你返回的promise为准
例1
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))
例2
async function async1 () {
console.log('async2');
throw new Error('error!!!')
return 'async1 success'
}
async1().then(res => console.log(res))
17.如果在async函数中抛出了错误,则执行终止
综合
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' undefined
'timer1'
Promise{<resolved>: undefined}
18.考点:状态一经改变就不能再改 ,finally不管状态是resloved还是rejected都会执行,它的回调函数是接收不到promise结果的,所以为undefined;打印p1就是打印finally的返回值 finally接收不到promise的结果 它默认是上一个promise也就是then的返回值 但是then没有return所以就是undefined
原文来自:juejin.cn/post/684490…