Promise是什么?
1. 抽象表达:
Promise 是 JS 中进行异步编程的新的解决方案(旧的是使用回调函数和事件)
2. 具体表达:
(1) 从语法上来说:Promise 是一个构造函数
(2) 从功能上来说:promise 对象用来封装一个异步操作并可以获取其结果
promise可以解决异步的问题,本身不能说promise是异步的
promise 的状态改变
- pending(进行中,初始状态) ----> fulfiled(成功,操作已成功)
- pending(进行中,初始状态) ----> rejected(失败,操作已失败)
说明: 只有这 2 种状态改变, 且一个 promise 对象只能改变一次
无论变为成功还是失败, 都会有一个结果数据成功的结果
数据一般称为 vlaue, 失败的结果数据一般称为 reason
promise基本流程
promise基本使用
使用new来构建一个Promise。Promise接受一个「函数」作为参数,该函数的两个参数分别是resolve和reject。这两个函数就是「回调函数」,由JavaScript引擎提供。
resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
//构建Promise
const promise=new Promise((resolve, reject)=> {
//执行异步操作
setTimeout(()=>{
const time=Date.now()
//时间奇数成功,否则失败
if (time%2===1) {
/* 异步操作成功 */
resolve('成功')
} else {
/* 异步操作失败 */
reject('失败')
}},1000)})
//通过promise的then()指定成功和失败的回调函数
promise.then(
// 成功时
value=>{console.log('成功的回调')
}, reason=>{//失败时
console.log('失败的回调')
}
)
Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数
为什么要用 Promise?
- 指定回调函数的方式更加灵活
- 旧的: 必须在启动异步任务前指定
- promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函 数(甚至可以在异步任务结束后指定/多个)
- 支持链式调用, 可以解决回调地狱问题
1. 回调地狱
在用JavaScript时,为了实现某些逻辑会用到函数嵌套,但是嵌套过多会形成一个回调地狱(回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件),影响对代码的理解以及可读性
//回调地狱
doSomenthing(function (result) {
doSomenthingElse(result, function (newResult) {
doThirdThing(newResult, function (finalResult) {
console.log(fianlResult);
}, failureCallback)
}, failureCallback)
}, failureCallback)
2.Promise 链式调用解决回调地狱
采用链式的then通过异步操作实现按顺序从上至下进行。上一个then里的回调函数返回一个promise对象,下一个then的回调函数会等上一个then里的函数返回的promise对象状态发生变化,才会被调用。
doSomenthing()
.then(function (result) {
return doSomethingElse(result)
})
.then(function (newResult) {
return doThirdthing(newResult)
})
.then(function (finalResult) {
console.log(finalResult);
})
.catch(failureCallback)
3. async/await解决回调地狱
async
是协同Promise工作的,放置在函数前面,返回一个Promise对象,关键词await
可以让JavaScript进行等待,直到一个promise执行并返回它的结果,JavaScript才会继续往下执行,await只能在async定义的函数内部执行。
async function request() {
try {
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdthing(newResult)
console.log(finalResult);
} catch (error) {
failureCallback
}
}