2026-05-22 fetch 与 Promise:本质区别与协同使用指南(deepseek)
fetch 和 Promise 不是同一层级的对比对象,因为 fetch 返回的就是 Promise。
更准确的对比应该是:fetch 和 axios/XMLHttpRequest 的区别,或者 Promise 和 async/await/回调函数 的区别。
核心关系
// fetch 返回一个 Promise
const promise = fetch('/api/data'); // promise 是一个 Promise 对象
// 所以可以用 .then()
promise.then(response => response.json());
// 也可以用 async/await
const response = await fetch('/api/data');
1. fetch 是什么?
fetch 是一个浏览器原生 API,用于发起网络请求。
// fetch 的基本用法
fetch('https://api.example.com/users')
.then(response => response.json()) // 解析 JSON
.then(data => console.log(data))
.catch(error => console.error('请求失败:', error));
2. Promise 是什么?
Promise 是一种异步编程的语法/对象,用于处理异步操作。
// 手动创建 Promise
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
// 或 reject('失败');
}, 1000);
});
myPromise.then(result => console.log(result));
3. 主要区别
| 维度 | fetch | Promise |
|---|---|---|
| 是什么 | 浏览器 API(发起网络请求) | JavaScript 异步编程对象 |
| 返回结果 | 返回 Promise 对象 | 返回 Promise 对象本身 |
| 主要用途 | 获取网络资源 | 处理任何异步操作 |
| 能否独立使用 | 是,直接调用 | 需要配合异步函数或手动 resolve |
| 错误处理 | 网络错误会 reject,HTTP 错误(404)不 reject | 通过 reject 或 throw 触发 catch |
4. 代码对比
fetch 使用(内部自动创建 Promise)
// fetch 内部已经帮你创建了 Promise
fetch('/api/user')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
手动创建 Promise(模拟 fetch)
// 你自己模拟 fetch 的实现
function myFetch(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject('网络错误');
xhr.send();
});
}
// 用法和 fetch 一样
myFetch('/api/user')
.then(data => console.log(data))
.catch(err => console.error(err));
5. 各自的特性
fetch 的特性(作为网络请求 API)
// 1. 默认不带 cookie
fetch('/api/data', {
credentials: 'include' // 需要手动开启
});
// 2. 只有网络错误才 reject,HTTP 404 不会 reject
fetch('/not-found') // 不会进 catch,而是进 then
.then(res => {
if (!res.ok) throw new Error('HTTP 错误'); // 需要手动处理
return res.json();
});
// 3. 支持请求/响应拦截(需要封装)
// 4. 支持流式处理(Response.body)
Promise 的特性(作为异步编程工具)
// 1. 链式调用
doSomething()
.then(result => doSomethingElse(result))
.then(finalResult => console.log(finalResult))
.catch(error => console.error(error));
// 2. 并发处理
Promise.all([fetch('/user'), fetch('/posts')])
.then(([user, posts]) => console.log(user, posts));
Promise.race([fetch('/fast'), fetch('/slow')])
.then(first => console.log(first));
// 3. 状态管理
const pendingPromise = new Promise(() => {}); // pending 状态
const resolvedPromise = Promise.resolve('完成'); // resolved 状态
const rejectedPromise = Promise.reject('失败'); // rejected 状态
// 4. 错误冒泡
Promise.resolve()
.then(() => { throw new Error('错误'); })
.then(() => console.log('不会执行'))
.catch(err => console.log('在这里捕获')); // 错误会一路向下直到 catch
6. 结合使用的常见模式
// 模式1:fetch + .then() + .catch()
fetch('/api/user')
.then(res => res.json())
.then(data => {
console.log('用户数据:', data);
return fetch(`/api/posts?userId=${data.id}`);
})
.then(res => res.json())
.then(posts => console.log('用户帖子:', posts))
.catch(err => console.error('请求失败:', err));
// 模式2:fetch + async/await(推荐)
async function getUserAndPosts() {
try {
const userRes = await fetch('/api/user');
const user = await userRes.json();
const postsRes = await fetch(`/api/posts?userId=${user.id}`);
const posts = await postsRes.json();
console.log('用户帖子:', posts);
} catch (error) {
console.error('请求失败:', error);
}
}
// 模式3:fetch + Promise.all(并发请求)
async function getMultipleResources() {
try {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()),
fetch('/api/comments').then(res => res.json())
]);
console.log({ users, posts, comments });
} catch (error) {
console.error('某个请求失败:', error);
}
}
7. 错误处理的关键区别
// fetch 的特殊性:网络错误才 reject
fetch('https://invalid-domain-12345.com') // 域名不存在
.catch(err => console.log('网络错误,会进这里'));
fetch('/api/not-exist') // HTTP 404
.then(res => {
console.log('HTTP 404 也会进这里,res.ok = false');
if (!res.ok) throw new Error('HTTP 错误');
return res.json();
})
.catch(err => console.log('手动 throw 后才能进这里'));
// 普通 Promise:reject 或 throw 都会进入 catch
Promise.reject('直接 reject')
.catch(err => console.log('会进这里'));
Promise.resolve()
.then(() => { throw new Error('throw 错误'); })
.catch(err => console.log('也会进这里'));
总结
| 如果你想... | 使用... |
|---|---|
| 发起网络请求获取数据 | fetch() |
| 处理异步操作(定时器、读取文件等) | new Promise() |
| 优雅地处理多个并发请求 | Promise.all() / Promise.race() |
| 让异步代码更易读 | async/await(配合 Promise) |
| 手动控制异步流程(延迟、重试等) | new Promise() + resolve/reject |
简单记忆:
- fetch = 专门用来请求数据的工具(返回 Promise)
- Promise = 处理所有异步操作的通用机制(包括 fetch 的结果)

浙公网安备 33010602011771号