(旧的是纯回调)
Promise状态
pending变为resolved;pending变为rejected
说明:
new Promise( function(resolve, reject) {…} /* executor */ );
executor是带有 resolve 和 reject 两个参数的函数 。 Promise构造函数执行时立即调用executor 函数,
resolve 和 reject 两个函数作为参数传递给executor(executor
函数在Promise构造函数返回所建promise实例对象前被调用)。 resolve 和 reject
函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor
内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功/失败),要么调用resolve函数来将promise状态改成fulfilled,要么调用reject
函数将promise的状态改为rejected。如果在executor函数中抛出一个错误,那么该promise
状态为rejected。executor函数的返回值被忽略。
//1.创建一个新的promise对象--传入的参数是一个回调函数,也就是定义中所说的执行器函数
//尽量使用const变量
const p = new Promise((resolve, reject) => {
//执行器函数是同步回调!!!
console.log('执行 excutor') //是会立刻执行的
//2.执行异步操作
setTimeout(() => {
const time = Date.now()//如果当前时间是偶数就代表成功,否则代表失败
//3.1 如果成功了,调用resolve(value)
if( time % 2 === 0 ){
resolve('成功的数据,time=' + time)
} else {
//3.2 如果失败,调用reject(reason)
reject('失败的数据,time=' + time)
}
}, 1000)
})
console.log('new Promise()之后') //先输出执行 excutor
// then()指定成功或失败的回调函数
p.then(
value => {
//接收得到成功的value数据 onResolved: 当变为resolved时执行
console.log('成功的回调', value)
},
reason => {
//接收失败得到的reason onRejected
console.log('失败的回调', reason)
}
)
执行 excutor
new Promise()之后
失败的回调 失败的数据,time=1586181072611 //promise定义时,reject(reason)
//伪代码
function successCallback(result) {
console.log('声音文件创建成功' + result)
}
function failureCallback(error) {
console.log('声音文件创建失败' + error)
}
/* 1.1 纯回调函数 */
//启动任务(audioSettings)前必须指定回调函数(callback)
createAudioFileAsync(audioSettings, successCallback, failureCallback)
/* 1.2 promise */
//可在启动任务(audioSettings)后指定回调函数(callback)
const promise = createAudioFileAsync(audioSettings)
setTimeout(() => {
promise.then(successCallback, failureCallback)
}, 1000)
/* 2.1 回调地狱 */
//回调函数的嵌套
doSomething1(function (result) {
//参数一:function(result)就是sucessCallback,接收成功的结果result
doSomethingElse2(result, function (newResult) {
doThirdThing3(newResult, function (finalResult) {
console.log('Got the final result' + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
/* 2.2 promise链式调用 */
doSomething().then(function(result) {
//result是doSomething函数成功执行的返回值
return doSomethingElse(result) //执行器函数,同步回调
})
.then(function(newResult){
//newResult是doSomethingElse成功执行的返回值
return doThirdThing(newResult)
})
.then(function(finalResult){
console.log('Got the final result' + finalResult)
})
.catch(failureCallback) //统一的错误处理,上面无论哪个promise出了问题,都会到这里:异常传透
/* 2.3 async/await : 回调地狱的终极解决方案 */
//根本上去掉回调函数
async function request() {
try{
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdThing(newResult)
console.log('Got the final result' + finalResult)
} catch (error) {
failureCallback(error)
}
}
Promise构造函数: Promise(excutor){}
excutor函数:同步执行(resolve,reject)=>{}
resolve函数: 内部定义成功时我们调用的函数 value={}
reject函数:内部定义失败时我们调用的函数 reason={}
说明:excutor会在Promise内部立即同步回调,异步操作在执行器中执行
Promise.prototype.then方法:(onResolved, onRejected)=>{}
onResolved函数:成功的回调函数 (value)=>{}
onRejected函数:失败的回调函数(reason)=>{}
说明:指定 用于得到成功value的成功回调 和 用于得到失败reason的失败回调,返回一个新的 promise对象
Prmise.prototype.catch方法:(onRejected)=>{}
onRejected函数:失败的回调函数 (reason)=>{}
说明:then()的语法糖,相当于then(undefined, onRejected)
快速创建promise对象
Promise.resolve方法:(value)={}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
Promise.reject方法:(reason)=>{}
reason:失败的原因
说明:返回一个失败的promise对象
Promise.all方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 只有所有的promise都成功才成功,只要有一个失败了就直接失败
Promise.race方法: (promises) => {}
promises: 包含n个promise的数组
说明: 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
new Promise((resolve, reject) => {
setTimeout( () => {
resolve('成功') //resolve就像是一个传递数据的运输机
// reject('失败') 指定了也没有,promise状态只能改变一次
}, 1000 )
})
.then(
value => {
console.log('onResolved()1', value)
}
)
.catch(
reason => {
console.log('onRejected()1', reason) //如果上面指定了reject('失败'),就走到这里
}
)
// 产生一个成功值为1的promise对象
const p1 = new Promise((resolve, reject) => {
resolve(1)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
p1.then( value => {
console.log(value)} )
p2.then( value => {
console.log(value)} )
p3.catch( reason => {
console.log(reason)} )
//const pAll = Promise.all([p1,p2,p3]) 三个异步请求
const pAll = Promise.all([p1,p2])//完全跟在这个数组里的顺序有关,跟异步完成的顺序无关
pAll.then(
values => {
console.log('all onResolved()', values)
},
reason => {
console.log('all onRejected()', reason)
}
)
// Promise.race: 看谁先完成(比赛)
const pRace = Promise.race([p1,p2,p3])
pRace.then(
value => {
console.log('race onResolved()', value)
},
reason => {
console.log('race onResolved()', reason)
}
)
(1)resolve(value):如果当前是pending,就会变成resolved
(2)reject(reason):如果当前是pending,就会会变成rejected
(3)抛出异常:如果当前是pending,就会会变成rejected
const p =new Promise((resolve, reject)=>{
// resolve(1) promise变为resolved成功状态
// reject(2) promise变为rejected失败状态
// throw new Error('出错了') 抛出异常,promise变为 rejected失败状态,reason为 抛出的error
throw 3 //抛出异常,promise变为rejected失败状态,reason为 抛出的3
})
p.then(
value =>{
},
reason =>{
console.log('reason', reason)}
)
error属于promise哪个状态
// const p = new Promise((resolve, reject)=>{
// throw new Error('出错了') //属于reject状态
// })
// p.then(
// value => {},
// reason => { console.log('reason', reason) } //reason Error: 出错了
// )
一个promise指定多个成功/失败回调函数,都会调用吗?
当promise改变为对应状态时,都会调用
const p2 = new Promise((resolve, reject)=>{
throw new Error('出错了') //属于reject状态
})
p2.then(
value => {
},
reason1 => {
console.log('reason1', reason1) } //reason1 Error: 出错了
).then(
reason2 => {
console.log('reason2', reason2) } //reason2 undefined
)
(1)都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
(2)如何先改变状态再指定回调
(3)什么时候才能得到数据?
/* 3.状态改变与指定回调函数的先后次序 */
new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(1) //后改变状态(同时指定数据),异步执行 回调函数
},1000) //有定时器
}).then( //先指定回调函数, 所以保存 当前指定的回调函数
value => {
},
reason => {
console.log('reason', reason) }
)
new Promise((resolve, reject)=>{
resolve(1) //先改变状态(同时指定数据)
}).then( //后指定回调函数,异步执行 回调函数
value => {
console.log('value', value) },
reason => {
console.log('reason', reason) }
)
console.log('-----') //先输出----, 再输出value 1
由then()指定的回调函数 执行的结果 决定
new Promise((resolve, reject)=>{
resolve(1)
}).then(
value => {
console.log("onResolved1()", value)//1 这个promise return undefined, 下个then得到的value就是undefined
},
reason => {
console.log("onRejected1()", reason)//这个promise return undefined, 下个then得到的value就是undefined
})
.then(
value => {
console.log("onResolved2()", value)//undefined
},
reason => {
console.log("onRejected2()", reason)
}
)
//进一步
new Promise((resolve, reject)=>{
resolve(1)
}).then(
value => {
console.log("onResolved1()", value)
//return 2 //新Promise状态为resolved, return得到value值
//return Promise.resolve(3) //返回一个新promise, Promise是函数对象
throw 4 //新Promise状态为rejected, throw得到value值
}
).then(
value => {
console.log("onResolved2()", value)},
reason => {
console.log("onRejected2()", reason)}
)
/* 5. promise如何串联多个操作任务
(1)promise的then返回一个新的promise, 可以看成then()的链式调用
(2)通过then的链式调用串联起多个同步/异步任务
*/
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行任务1(异步)')
resolve(1)
}, 1000)
}).then(
value => {
console.log('任务1的结果', value)
console.log('执行任务2(同步)')
return 2
}
).then(
value => {
console.log('任务2的结果', value)
return new Promise((resolve, reject) => {
//启动的异步任务要放在promise里
//启动任务3(异步)
setTimeout(() => {
console.log('执行任务3(异步)')
resolve(3)
}, 1000)
})
}
).then(
value => {
console.log('任务3的结果', value)
}
)
// 执行任务1(异步)
// 任务1的结果 1
// 执行任务2(同步)
// 任务2的结果 2
// 执行任务3(异步)
// 任务3的结果 3
/* 6. 异常传透
(1)当使用promise的then链式调用时,可以在最后指定失败的回调
(2)前面任何操作出了异常,都会传到最后失败的回调中处理[一层一层传递]
*/
new Promise((resolve, reject) => {
//resolve(1)
reject(1)
}).then(
value => {
console.log('onResolved1()', value)
return 2
},
// reason => throw reason 在这个then只写了成功的回调,相当于有这句话:默认failureCallback
//reason => Promise.reject(reason)
).then(
value => {
console.log('onResolved2()', value)
return 3
}
// reason => throw reason 在这个then只写了成功的回调,相当于有这句话:默认failureCallback
).then(
value => {
console.log('onResolved3()', value)
// reason => throw reason 在这个then只写了成功的回调,相当于有这句话:默认failureCallback
}
).catch(reason => {
console.log('onRejected1()', reason)
})
/* 7. 中断Promise链
(1)当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
(2)办法:在回调函数中返回一个pending状态的promise对象
*/
new Promise((resolve, reject) => {
reject(1)
}).then(
value => {
console.log('onResolved1()', value)
return 2
}
).then(
value => {
console.log('onResolved2()', value)
return 3
}
).then(
value => {
console.log('onResolved3()', value)
}
).catch(reason => {
console.log('onRejected1()', reason)
return new Promise(()=>{
}) //返回一个pending的promise 中断promise链
}).then(
value => {
console.log('onResolved4()', value) },
reason => {
console.log('onRejected4()', reason)}
)
/*
1.async function (function return Promise)
函数返回Promise对象
promise对象的结果由async函数执行的返回值决定
2. await expression (value or Promise)
expression一般是Promise对象,也可以是其他值
如果是Promise对象,await返回的是Promise成功的值
如果是其他值,直接将此值作为await的返回值
3.
await必须写在async中,但async可以没有await
如果await的Promise失败,就会抛出异常,需通过try...catch...捕获处理
*/
// async函数返回一个promise对象
async function fn1() {
//return 1
//throw 2
//return Promise.resolve(3)
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(4)
}, 1000)
})
}
const result = fn1()
//console.log(result) //Promise { 1 }
result.then(
value => {
console.log('onResolved()', value)
},
reason => {
console.log('onRejected()', reason)
}
)
/*------------------------*/
function fn2(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
//resolve(4)
reject(6)
}, 1000)
})
}
function fn4(){
return 5
}
async function fn3(){
//const value = await fn2() //await右侧表达式为Promise,得到的结果就是promise成功的value
const value = await fn4() //await右侧表达式不为Promise,得到的结果就是它本身
console.log('value', value)
}
fn3()
async function fn5(){
try{
const value = await fn2()
console.log('fn5 value', value)
}catch(error){
//捕获失败promise的结果
console.log('fn5 error', error)
}
}
fn5()
/*
宏队列:
定时器回调
ajax回调
dom事件回调
微队列:
Promise回调
mutation回调
*/
// setTimeout(()=>{ //立即放入宏队列
// console.log('timeout callback1()')
// Promise.resolve(3).then(
// value => { //立即放入微队列
// console.log('Promise onResolved3()', value)
// }
// )
// },0)
// setTimeout(()=>{ //立即放入宏队列
// console.log('timeout callback2()')
// },0)
// Promise.resolve(1).then(
// value => { //立即放入微队列
// console.log('Promise onResolved1()', value)
// setTimeout(()=>{
// console.log('timeout callback3()', value)
// },0)
// }
// )
// Promise.resolve(2).then(
// value => { //立即放入微队列
// console.log('Promise onResolved2()', value)
// }
// )
// 先执行微队列
// Promise onResolved1() 1
// Promise onResolved2() 2
// timeout callback1()
// timeout callback2()
// timeout callback3() 1
// Promise onResolved3() 3
/* ----------------------- */
setTimeout(()=>{
console.log(1)
},0)
new Promise((resolve, reject) => {
console.log(2)
resolve()
}).then(
value => {
console.log(3)
}
).then(
value => {
console.log(4)
}
)
console.log(5)