网络请求异步封装

2022/11/13

# 后端思路

# 处理请求

// 模拟异步操作数据库
const db = {
    query(sql, param, callback) {
        setTimeout(() => {
            const ans = sql + 1;
            callback(ans);
        }, 1000);
    }
}

// 回调地狱写法
const get = () => {
    db.query(1, {}, (ans1) => {
        db.query(ans1 * 2, {}, (ans2) => {
            db.query(ans2 + 100, {}, (ans3) => {
                console.log(ans3);
            })
        })
    })
}

get();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Promise封装

const db = {
    query(sql, param, callback) {
        setTimeout(() => {
            const ans = sql + 1;
            console.log(ans);
            callback(ans);
        }, 1000);
    }
}

// 链式封装
const query = (sql, param) => {
    return new Promise((resolve) => {
        db.query(sql, param, (ans) => {
            resolve(ans);
        })
    })
}

// 使用
const get = () => {
    query(1, {}).then(ans1 => query(ans1 * 2, {}))
        .then(ans2 => query(ans2 + 100, {}))
        .then(ans3 => console.log(ans3))
}

get();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# async封装

const db = {
    query(sql, param, callback) {
        setTimeout(() => {
            const ans = sql + 1;
            console.log(ans);
            callback(ans);
        }, 1000);
    }
}

// async封装
const query = async (sql, param) => {
    return await new Promise((resolve) => {
        db.query(sql, param, (ans) => {
            resolve(ans);
        })
    })
}

// 使用
const get = async () => {
    const ans1 = await query(1, {})
    const ans2 = await query(ans1 * 2, {});
    const ans3 = await query(ans2 + 100, {});
    console.log(ans3)
}

get();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 前端思路

# 回调地狱问题

const axios = (method, url, params) => {
    return new Promise(resolve => {
        console.log(`发送${method}请求给${url}处理${params}`);
        setTimeout(() => {
            resolve(params + 1);
        }, 1000);
    })
}

// 组件内调用
axios("get", "/api1", 100).then(data1 => {
    console.log(`结果是${data1}`);
    axios("post", "/api2", data1).then(data2 => {
        console.log(`结果是${data2}`);
        axios("post", "/api3", data2).then(data3 => {
            console.log(`最终结果:${data3}`);
        })
    })
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 请求method封装

const axios = (method, url, params) => {
    return new Promise(resolve => {
        console.log(`发送${method}请求给${url}处理${params}`);
        setTimeout(() => {
            resolve(params + 1);
        }, 1000);
    })
}

const get = (url, params) => {
    return new Promise(resolve => {
        axios("get", url, params).then(data => {
            resolve(data);
        });
    })
}

const post = (url, params) => {
    return new Promise(resolve => {
        axios("post", url, params).then(data => {
            resolve(data);
        });
    })
}

// 组件内调用
get("/api1", 100).then(data1 => {
    console.log(`结果是${data1}`);
    return post("/api2", data1)
}).then(data2 => {
    console.log(`结果是${data2}`);
    return post("/api3", data2)
}).then(data3 => {
    console.log(`最终结果:${data3}`);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# async封装

const axios = (method, url, params) => {
    return new Promise(resolve => {
        console.log(`发送${method}请求给${url}处理${params}`);
        setTimeout(() => {
            resolve(params + 1);
        }, 1000);
    })
}

const get = async (url, params) => {
    return await axios("get", url, params);
}

const post = async (url, params) => {
    return await axios("post", url, params)
}

// 组件内调用
const getData = async () => {
    const data1 = await get("/api1", 100);
    console.log(`结果是${data1}`);

    const data2 = await post("/api2", data1);
    console.log(`结果是${data2}`);

    const data3 = await post("/api3", data2);
    console.log(`最终结果:${data3}`);
}

getData();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# fetch完整封装

  • fetch的post请求必须设置 headers['Content-Type'] = 'application/json'
  • express必须设置body-parser
const BASE_URL = "http://127.0.0.1:8888/";
const defaultConfig = {
    mode: "cors",
    credentials: "include",
    keepalive: true,
}
const commonRequest = async (method, url, config = {}) => {
    try {
        const ans = await fetch(`${BASE_URL}${url}`, {
            method,
            ...defaultConfig,
            ...config
        });
        console.log(config);
        const data = await ans.json();
        console.log(data);
    } catch (e) {
        console.warn(e);

        // check
        return { error: e };
    }
}

const get = async (url, params, config) => {
    const query = `?${Object.entries(params).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&")}`;
    url = query.length === 1 ? url : `${url}${query}`;
    return commonRequest("get", url, config)
}

const post = async (url, params = {}, config = {}) => {

    // check:其他数据类型
    if (typeof params === "object") {
        config.body = typeof params === "object" ? JSON.stringify(params) : params;
        config.headers = { ...config?.headers, 'Content-Type': 'application/json' };
    }
    return commonRequest("post", url, config)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 调用测试

上次更新: 6/13/2025