有时候会遇到一些情况,比如在点击事件触发的时候,我需要发送两次或以上的 http 请求,而这两次请求时相关的,即第二次 http 请求的参数需要携带第一次 http 请求的结果,这种时候,一般的处理如下:
function f() {
$.get('xxx1.json', function(res1) {
var m = res1.id // 假设返回一个对象,该对象的属性id,需要作为参数再次发送请求
$.post('xxx2.json', {id: m}, function(res2) {
console.log(res2) // 这里返回的 res2 就是我想要的结果
})
})
}
上述写法,很麻烦,如果遇到两次以上的请求时,会容易出错。
这时候,我们可以利用 promise 的 then 的写法进行封装:
function f1() {
return new Promise((resolve, reject) => {
// 这里用 setTimeout 模拟 http 请求
setTimeout(() => {
var result = {
id: 10
}
resolve(result) // 假设这个 result 就是第一次请求返回的结果,这个结果的 id 值将作为参数传递给第二次请求
}, 2000)
})
}
function f2(param) {
// 这里的 param 参数就是第一次 http 请求的结果(result.id的值),这里将作为第二次 http 请求的参数
return new Promise((resolve, reject) => {
// 这里用 setTimeout 模拟 http 请求
setTimeout(() => {
var n = 20
resolve(n) // 假设这里的 n 的值就是第二次请求利用 result.id 作为实参的结果
}, 1000)
})
}
// promise.then 的写法
f1().then(res1 => {
var id = res1.id
f2(id).then(res2 => {
console.log(res2)
})
})
上述方法同样可以用 async/await 实现:
// async/await 的写法
async function test() {
var s1 = await f1() // s1 表示第一次 http 返回的结果
var s2 = await f2(s1.id) // s2 表示利用第一次 http 返回的结果(result.id),作为第二次 http 请求的参数,而得到的结果
console.log(s2)
}
test()
如此看来,利用 async/await 写法,使代码结构和逻辑更清晰、易读。
补充实例:对于看不懂的朋友,我写了一份实例,如下:
getInfo = () => {
return request({
method: 'get',
url: '/info',
header: {
"Content-type": "application/json",
}
})
}
getDetails = (id) => {
return request({
method: 'get',
data: {
userId: id
},
url: '/details',
header: {
"Content-type": "application/json"
}
})
}
function f1() {
return new Promise((resolve, reject) => {
getInfo().then(res => {
var res = {
id: 1,
name: 'sonovabitch'
}
resolve(res)
})
})
}
function f2(param) {
return new Promise((resolve, reject) => {
getDetails(param).then(res => {
var res = {
name: 'bitch',
age: 99
}
resolve(res)
})
})
}
// 第一种写法
f1().then(res1 => {
f2(res1.id).then(res2 => {
console.log(res2.name) // 'bitch'
})
})
// 第二种写法
async function test() {
var s1 = await f1()
var s2 = await f2(s1.id)
console.log(s2.name) // 'bitch'
}