本篇绪论
- 1,get请求传参的误区,get、post请求在缓存方面的区别
- 2, setTimeout、promise、async/await区别
- 3, 小程序跳转另一个小程序
1,get请求传参的误区,get、post请求在缓存方面的区别
实际上HTTP协议从未规定get/post请求长度限制是多少,对get请求参数的限制是浏览器或者web服务器,浏览器或web服务器限制了url的长度。不同的浏览器和web服务器限制的长度不一样
get、post请求在缓存方面的区别:
- get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。
- post不同,post做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此get请求适合于请求缓存
2, setTimeout、promise、async/await区别
首先看道面试题
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('settimeout')
})
async1()
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('promise2')
})
console.log('script end')
题目的本质是考察setTimeout、promise、async/await的实现及执行顺序,以及JS的事件循环的相关问题。

再看一个经典的例子
const p = Promise.resolve()
(async () => {
await p
console.log('await end')
})()
p.then(() => {
console.log('then 1')
}).then(() => {
console.log('then 2')
})

这里涉及到微任务、宏任务、event loop以及JS的异步运行机制
Event loop
JS主线程不断的循环往复的从任务队列中读取任务,执行任务,其中运行机制称为事件循环(Event loop)
宏任务、微任务
宿主(如浏览器)发起的任务称为宏观任务,JS引擎发起的任务称为微观任务。
宏任务大概包括:
- 定时器:setTimeout、setInterval、setImmediate
- I/O操作:比如读写文件
- 消息通道:MessageChannel
- script整体代码
微任务大概包括:
- promise.then
- async/await(等价于promise.then)
异步运行机制
因为JS是单线程的,JS主线程拥有一个执行栈(同步任务)和一个任务队列,主线程会依次执行代码。
- 当遇到函数(同步)时,会先将函数入栈,函数运行结束后再将该函数出栈
- 当遇到 task 任务(异步)时,这些 task 会返回一个值,让主线程不在此阻塞,使主线程继续执行下去,而真正的 task 任务将交给 浏览器内核 执行,浏览器内核执行结束后,会将该任务事先定义好的回调函数加入相应的任务队列(microtasks queue(微任务队列)/ macrotasks queue(宏任务队列))中
- 当JS主线程清空执行栈之后,会按先入先出的顺序读取microtasks queue中的回调函数,并将该函数入栈,继续运行执行栈,直到清空执行栈,再去读取任务队列。
- 当microtasks queue中的任务执行完成后,会提取 macrotask queue 的一个任务加入 microtask queue, 接着继续执行microtask queue,依次执行下去直至所有任务执行结束。
// 1,开始执行
console.log(1) // 2,打印 1
setTimeout(function () { // 6,浏览器在0s后,将该函数推入任务队列
console.log(2) // 7,打印 2
Promise.resolve(10).then(function () { // 8,将resolve(10)推入到任务队列。// 9,将function函数推入任务队列
console.log('ok') // 10,打印 ok
})
}) // 3,调用setTimeout函数,并定义其完成之后执行的回调函数
setTimeout(function (){
console.log(3)
}) // 4,调用setTimeout函数,并定义其完成后执行的回调函数
// 5,主线程执行栈清空,开始读取任务队列中的任务
setTimeout:
console.log(111) // 1, 打印 111
setTimeout(function () { // 4,打印 setTimeout
console.log('setTimeout')
}) // 2,调用setTimeout函数,并定义其完成后执行的回调函数
console.log(222) // 3,打印 222
Promise:
promise本身是同步的立即执行函数,当在执行resolve或reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('script end')

const p = Promise.resolve() // 1, p 的状态是 reslove
(async () => {
await p // 2,返回,并将函数后面的语句console.log('await end')放入下一个事件循环的微任务中
console.log('await end') // 6,执行,打印 await end
})()
p.then(() => { // 3,p的状态为resolve,会把p.then()放入当前事件循环的微任务中
console.log('then 1') // 4,执行,打印 then 1
}).then(() => {
console.log('then 2') // 5,执行,打印 then 2 当前微任务结束,运行下一个微任务
})
以上输出结果为:then 1 => then 2 => await end
async/await
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
async函数返回一个promise对象,当函数执行的时候,一旦遇到await就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出async函数体。

async function fun () {
return 1
}
console.log(fun())

很显然,fun的运行结果其实就是一个promise对象,因此我们可以使用then来处理后续逻辑
fun().then(res => {
console.log(res) // 1
})
await的含义为等待,也就是async函数需要等待await后的函数执行完成并且有了返回结果(promise对象)之后,才能继续执行下面的代码。await通过返回一个Promise对象来实现同步的效果。
3,小程序跳转另一个小程序
wx.navigateToMiniProgram({
appId: 'xxx', // 必填
path: 'pages/index/index', // 如果为空,则打开首页 path中?后面的部分回传成为query,在小程序的App.onLaunch、App.onShow和Page.onLoad的毁掉函数中可以获取到query参数
extraData: { // 非必填,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch,App.onShow 中获取到这份数据
platform: 1
},
envVersion: 'release', // 非必填 要打开的小程序版本。仅在当前小程序为开发版或体验版时此参数有效。如果当前小程序是正式版,则打开的小程序必定是正式版。
success(res) {
}
})
object.envVersion 的合法值
- develop 开发版
- trial 体验版
- release 正式版
网友评论