Promise/ fetch / async await 我终于学会啦 ...
爷爷,你关注的作者更新啦!
上周五的某个timing:
【突然发现】某个功能没有实现
--
【噢原来是】js没有执行--
【认真debug】js异步没执行完--
【改bug】花了不少时间 -- 【继续深究下去】终于搞明白Promise、async/await和fetch,3个东东之间的关系好记性不如烂笔头,以下展开10000
00000字
Promise
MDN文档指路:
Overview
-
Promise 是
JavaScript
中实现异步执行
的方式之一英文中表示
“承诺”
,意味着在未来会返回执行结果 -
Promise 是一个对象,有3种状态:
pending - 未完成(执行中)
fulfilled - 成功
rejected - 失败
pending是初始状态,之后变成fulfilled或rejected状态,而且状态不会逆转、不会更改。
类似于煮米饭,生米(pending)只会变熟(fulfilled),或者不熟(rejected)
不熟的米饭不可能变熟 // 除非重新煮(再次使用Promise)
怎么用
-
通过 new Promise( function(){} )
-
必须传入一个
函数
作为参数,函数有两个参数resolve
reject
- resolve( 返回值 ) - 函数成功时使用
- reject( 返回值 ) - 函数失败时调用
返回值
可有可无
,没有就返回undefined成功还是失败,当然是programmer自由发挥,想怎样都不会犯法kkk
只能通过
resolve
或reject
函数来返回(改变Promise的状态),不能return
- new的同时,会
立即执行
这个函数
试水,比如定义一个随机小数,比5大就返回success,否则返回error
let JoyTT = new Promise(function (resolve, reject) {
let num = Math.random() * 10
if (num > 5) {
resolve('success')
} else reject('error')
})
其实可以看出,resolve和reject也是函数,括号内第一个参数会作为返回值,后续可以通过.then() / .catch() 获取返回值
方法(prototype)
.then()
完整写法:Promise对象.then(function result(){},function error(){})
- 用于接收Promise成功执行的结果(
resolve(返回值)
) function error(){}
- Promise失败执行时触发,非必要,一般推荐直接用.catch()方法捕捉错误- 返回值:Promise对象
so,then() 方法后可以继续用
then()
获取上一层then()
的返回值which is 链式调用
.catch()
完整写法:Promise对象.catch(function error(){})
- 用于捕捉错误
链式调用时,如果过程中任意then()发生错误,就会直接跳到这里被捕捉
.finally()
完整写法:Promise对象.finally(function(){})
- 无论失败与否都会执行,通常用于执行清理操作或收尾工作
链式调用
多个then()+[catch()] +[finally()]
JoyTT()
.then(result => {
// 第一个异步操作成功后的处理
return anotherAsyncFunction(result);
},
error=>{})
.then(result => {
// 第二个异步操作成功后的处理
return yetAnotherAsyncFunction(anotherResult);
},
error=>{})
.catch(error => {
// 处理任何异常情况
console.error("发生错误:", error);
})
.finally(() => {
// 执行清理操作
console.log("清理操作完成");
});
静态方法(其他)
- Promise.all()
- Promise.race()
- Promise.any()
- Promise.allSettled()
fetch
MDN文档指路: Fetch API
Overview
-
基于
Promise
,用于发送网络请求 -
返回值:
Promise对象
对返回值使用
.json()
方法,将body解析为可以直接使用的json格式
prototype里还有别的api可以使用
注意:和Promise的原型是不一样的
- 用
.then()
.catch()
接收执行结果 捕捉错误
和
try-catch
一样,实现同样的功能
语法
写法:fetch(url,{请求参数})
- 默认发送get请求,发送其他类型请求必须配置请求参数
比如,post请求
{
method:"post",
body:JSON.stringify({ name: "data" }),
headers:{
"Content-Type":"application/json"
}
}
怎么用
因为文档讲解的很好,所以here省略200字 使用Fetch
async await
MDN文档指路: async function
Overview
- async/await是
Promise
的语法糖,优化了then()链式调用的问题
async - 将普通函数标记为异步函数
-
返回值:promise对象
-
在内部使用
return语句
返回的值,需要用then()方法
接收
await - 等待异步操作执行完毕,阻塞进程
- 在async函数内部使用
- 对同步操作不起效
语法
其实就是在 函数前面 加个async标志
-
async function f () { }
-
async ( () => { } )
怎么用
打个比方,在map方法的回调函数中使用async/await:遍历每一个数组项时,发fetch请求获取 xx 网址的数据
var array = [{role:'Sr. PM'},{role:'Ass. BA'},{role:'Tech Lead'},{role:'QA'}]
array.map(async (role, index) => {
fetchXml = `?fetchXml=
<fetch xmlns:generator="MarkMpn.SQL4CDS" aggregate="true">
<entity name="joy_costtrackingtask">
<attribute name="joy_pe" alias="PE" aggregate="sum" />
<attribute name="joy_pc" alias="PC" aggregate="sum" />
<attribute name="joy_ae" alias="AE" aggregate="sum" />
<attribute name="joy_ac" alias="AC" aggregate="sum" />
<filter>
<condition attribute="joy_costtracking" operator="eq" value="0000-0000" />
</filter>
</entity>
</fetch>`;
await fetch("https://example.com/joy_costtracking" +fetchXml).then(
function success(result) {
console.log(result,'success')
},
function (error) {
console.log(error.message);
}
);
})
-
let value = await 一个promise函数
value就是promise内部resolve的值
陷阱
如果循环中有await语句
,那需要使用for循环, 不能用map和forEach来循环,因为他会立刻返回不会等待
for await
也行
所以在刚刚的例子中,应该用传统的for循环来遍历
- 如果坚持用map,那么需要在外层使用Promise.all()
总结
- fetch()基于Promise,对于请求返回的数据需要
json()
格式化 - 获取async函数的返回值:
- async内部中直接return
- 外部用then()方法接收
- Promise是一个对象
new Promise( (resolve, reject) => {} )
- new的同时,会立即执行括号内的函数
- 通过调用
resolve()
,reject()
返回异步操作的执行结果
.then()
方法 接收Promise对象成功的返回值- 链式调用
.catch()
方法 接收Promise对象失败的返回值- 捕捉错误
不存在十全十美的文章,就如同不存在彻头彻尾的绝望。
Life is hard, keep learning!
转载自:https://juejin.cn/post/7281208218176126976