- openAI: https://juejin.cn/post/7173447848292253704
- 国内可用:http://chat.cutim.top/#/chat/1001
- 虚拟号码:https://sms-activate.org/
await
- await后面的Promise对象,运行结果可能是rejected,那么会报错
- 报错了后面就不会执行了
- 所以最好把await命令放在try...catch代码块中。
javascript
async function fn(){
await Promise.reject('出错了') // await出错了,下面就不会执行了
await Promise.resolve('hello')
}
fn().then(res => {
console.log(res)
})
try {
// 把可能出错的代码,放在这里
const box = document.querySelector('.div')
box.innerHTML = 'wahh'
console.log(box)
} catch(err) {
// 一旦try中的代码,出错了,报错了,都会捕获到这里,并且控制台不会打印错误
console.log(err)
}
// console.log(123123)/
// ==> 应用 try-catch
async function fn(){
try {
await Promise.reject('出错了') // await出错了,下面就不会执行了
} catch(err) {
console.log(err)
}
// async 函数, 里面如果没有return,fn()执行完,结果是成功态的undefined
return await Promise.resolve('hello')
// return 'hello'
// return 666
}
fn().then(res => {console.log(res)})
await-promise.all
继发:一件事情发生后,继而发生另一件事 并发:同一时间执行多个任务
javascript
// 继发:一件事情发生后,继而发生另一件事 同步 串联
// 并发:同一时间执行多个任务 异步 并联
// 4. 多个await关键字后面的异步操作,如果不存在继发关系,最好让他们同时执行
const api_news = 'http://ajax-api.itheima.net/api/news'
const api_books = 'http://ajax-api.itheima.net/api/books'
const api_robot = 'http://ajax-api.itheima.net/api/robot?spoken=你好'
async function sendRequest(url){
return await fetch(url).then(res => res.json())
// console.log(fetch(url).then(res => res.json()))
// 1. fetch(url).then() 返回的是什么? promsie对象
// 2. let res = await fetch().then() ==> res是promise对象的结果
// 3. sendRequest() 它调用完,返回的 也是 promsie对象
}
// 继发:下一个请求的参数,如果是上一个接口返回值里面取
;(async () => {
// await 会阻塞后面代码的执行
let books = await sendRequest(api_books)
console.log(books)
let news = await sendRequest(api_news)
console.log(news)
let robot = await sendRequest(api_robot)
console.log(robot)
// 这样写,比较耗时,上一个接口返回值了,才能继续下一个请求的发送
})()
// 并发 三个请求没有关联
;(async () => {
let [books, news, robot] = await Promise.all([sendRequest(api_books),sendRequest(api_news),sendRequest(api_robot)])
console.log(books, news, robot)
})()
promise链式编程 => async / await
javascript
// 链式编程
// 需求:延时2s秒输出红色,然后再延时1s输出黄色,然后再延时3s输出绿色
// 回调函数的嵌套 ==> 回调地狱 , promise解决 => 终极方案 async/await
// const sleep = (msg, ms) => {
// return new Promise((resolve) => {
// setTimeout(() => {
// resolve(msg)
// }, ms)
// })
// }
// sleep('啊哈', 1000) 这个表达式的值是什么 ? 或者说它返回什么?
const sleep = (msg, ms) => new Promise(resolve => setTimeout(() => {resolve(msg)}, ms))
sleep('红色', 2000).then(res => {
// 1. .then() 中 ,不写return, 相当于then中没有返回值,返回一个成功态的promise,结果是undefined
// 2. 写了return 并且return的是一个promise对象,就要等这个promise对象状态的的结果,才能进入下一个then的回调中
console.log(res)
// resolve()
return sleep('黄色', 1000)
}).then(res => {
console.log(res)
// resolve()
return sleep('绿色', 3000)
}).then(res => {
console.log(res)
})
// async function fn(){
// let res1 = await sleep('红色', 2000)
// console.log(res1)
// let res2 = await sleep('黄色', 1000)
// console.log(res2)
// let res3 = await sleep('绿色', 3000)
// console.log(res3)
// }
// fn()
;(async () => {
let res1 = await sleep('红色', 2000)
console.log(res1)
let res2 = await sleep('黄色', 1000)
console.log(res2)
let res3 = await sleep('绿色', 3000)
console.log(res3)
})()
async不会阻塞function外部的执行
javascript
const sleep = (s) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(s)
}, s * 1000)
})
}
async function func1() {
const res1 = await sleep(1)
console.log('res1:', res1)
const res2 = await sleep(3)
console.log('res2:', res2)
}
async function func2() {
// await func1()
const res3 = await sleep(2)
console.log('res3:', res3)
const res4 = await sleep(4)
console.log('res4:', res4)
}
// await 阻塞的是async function里面的代码,不会阻塞外面的函数的执行
// console.log('top')
func1() // func1 是用async修饰了,是promise,内部又有await,异步的
func2()
// console.log('bottom')
// Q: 我想 func1 执行完,再执行func2?
// async function func3(){
// await func1()
// await func2()
// }
// func3()
func1().then(res => {
func2()
})
;(async () => {
await func1()
await func2()
})()
必要商城
https://apifox.com/apidoc/shared-fa9274ac-362e-4905-806b-6135df6aa90e/api-25684707
javascript
// 1. 设置基地址
axios.defaults.baseURL = 'http://123.57.109.30:3999'
// 2. 待会儿事件委托绑定
const oneUl = document.querySelector('#one')
const twoUl = document.querySelector('#two')
const threeUl = document.querySelector('#three')
// 3. 获取一级分类的数据,发请求
;(async () => {
// 一级分类
const {data:{list:oneRes}} = await axios.get('/api/categoryfirst')
console.log(oneRes)
const htmlArr = oneRes.map(el => {
return `
<li data-id=${el.firstId}>${el.firstName}</li>
`
})
oneUl.innerHTML = htmlArr.join('')
/* ==================== 二级分类的处理 ===================== */
oneUl.addEventListener('click', async (e) => {
if (e.target.tagName !== 'LI') return
const firstId = e.target.dataset.id
// 发送请求
const {data:{list:twoRes}} = await axios({
url:`/api/categorySecond?firstId=${firstId}`,
})
// console.log(twoRes)
const htmlArr = twoRes.map(el => {
return `
<li data-id=${el.secondId}>${el.secondName}</li>
`
})
twoUl.innerHTML = htmlArr.join('')
// 等二级分类有了数据,渲染好了之后,点
document.querySelector('#two li').click()
}) // end click
// 自动click一下,一级分类的第一个li标签
document.querySelector('#one li').click()
/* ==================== 三级分类的获取 ===================== */
twoUl.addEventListener('click', async (e) => {
if (e.target.tagName !== 'LI') return
const secondId = e.target.dataset.id
// 发送请求
const {data:{list:threeRes}} = await axios({
url:`/api/categoryThird?secondId=${secondId}`,
})
// console.log(twoRes)
console.log(threeRes)
const htmlArr = threeRes.map(el => {
return `
<li data-id=${el.thiredId}>${el.thiredName}</li>
`
})
threeUl.innerHTML = htmlArr.join('')
})
})()
Toast轻提示
javascript
const toastBox = document.querySelector('#myToast')
// 生成toast实例
const toast = new bootstrap.Toast(toastBox)
// 想要封装一个tip函数,就是我们自己输入的提示
const tip = (msg) => {
toastBox.querySelector('.toast-body').innerHTML = msg
toast.show()
}
注册页
https://apifox.com/apidoc/shared-fa9274ac-362e-4905-806b-6135df6aa90e/api-26239981
javascript
// 1. 建一个新的分支 git checkout -b m-register
// 2. 在新分支上做开发,写好功能后,先提交代码,commit
// 3. 切到master,去合并 git merge m-register
/* ==================== 用户注册功能 ===================== */
const btnRegister = document.querySelector('#btn-register')
const form = document.querySelector('form')
baidu.com ----> master
test.baidu.com ----> test
dev.baidu.com -----> dev
btnRegister.addEventListener('click', async () => {
// 点击按钮的时候,获取输入的username pwd
const data = serialize(form, {hash:true})
console.log(data)
console.log(data.username)
if (!data.username || !data.password) {
return tip('账号或密码不能为空哟~🥰~')
}
if (data.password.length < 6) return tip('密码长度应该大于6哦~🥰~')
// 发送请求
try {
const res = await axios({
url:'/register',
method:'post',
data
})
tip(res.data.message)
setTimeout(() => {
location.href = './login.html'
}, 500);
// console.log(res)
}catch(err) {
tip(err.response.data.message)
console.dir(err)
}
// console.log(res)
})