在JavaScript的世界中,所有代码都是单线程执行的。
单线程-----导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行(异步执行可以用回调函数实现)
异步操作会在将来的某个时间点触发一个函数调用
1.什么是promise
-
ES6 异步编程的一种解决方案,比传统的方案(回调函数和事件)更加的合理和强大
-
好处 异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
-
promise可以解决异步的问题,本身不能说promise是异步的
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。
2.promise状态
- promise有三个状态:
1、pending[待定]初始状态
2、fulfilled[实现]操作成功
3、rejected[被否决]操作失败
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
promise状态一经改变,不会再变。 - Promise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected。
这两种情况只要发生,状态就凝固了,不会再变了。 -
promise内部发生错误,不会影响到外部程序的执行。
-
无法取消
Promise
。一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。第三,当处于pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
3.用法
创造Promise
实例时,必须传入一个函数作为参数
new Promise(() => {});
new Promise(); // 报错
该函数可以接收另外两个由JavaScript引擎提供的函数,resolve
和reject
。函数作用:
-
resolve
——将Promise
对象的状态从pending
变为resolved
,将异步操作的结果,作为参数传递出去 -
reject
——将Promise
对象的状态从pending
变为rejected
,将异步操作报出的错误,作为参数传递出去
let promise = new Promise((resolve, reject) => {
// do something
if (true) {
// 将参数返回,供then方法使用
resolve("value");
} else {
// 将参数返回,供then方法使用
reject("error");
}
});
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。
promise.then(
value => {
// resolved时调用,value为resolve函数返回的参数
console.log(value);
},
err => {
// rejected时调用,err为reject函数返回的参数
console.log(err);
}
);
let state=1
function step1(resolve,reject){
console.log('洗菜开始')
if(state==1){
resolve('洗菜完成')
}else{
reject('洗菜出错')
}
}
function step2(resolve,reject){
console.log('做饭开始')
if(state==1){
resolve('做饭完成')
}else{
reject('做饭出错')
}
}
function step3(resolve,reject){
console.log('洗碗开始')
if(state==1){
resolve('洗碗完成')
}else{
reject('洗碗出错')
}
}
new Promise(step1).then(val => {
console.log(val)
return new Promise(step2)
}).then(val=>{
console.log(val)
return new Promise(step3)
}).then(val=>{
console.log(val)
return val
})
// 洗菜开始
// 洗菜完成
// 做饭开始
// 做饭完成
// 洗碗开始
// 洗碗完成
不带有任何参数
Promise.resolve()
方法允许调用时不带参数,直接返回一个resolved
状态的 Promise 对象
Promise.resolve();
// 相当于
new Promise(resolve => resolve(undefined))
async与await
async
确保了函数返回一个promise,即使其中包含非promise。
// 只能在async函数内部使用
let value = await promise
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('done!'), 1000)
})
let result = await promise // 直到promise返回一个resolve值(*)
alert(result) // 'done!'
}
f()
函数执行到(*)行会‘暂停’,在1s后输出'done!'
有了async/await,我们很少需要写promise.then/catch(try-catch)