























函数 r 处理异步迭代
function r(t, e, n, r, o, i, s) { try { var a = t[i](s), // 调用迭代器方法,例如 next() u = a.value; // 获取迭代返回的值 } catch (c) { return void n(c); // 处理异常 } a.done ? e(u) : Promise.resolve(u).then(r, o); // 如果迭代完成,调用 e 处理最终值,否则递归处理 Promise 以执行后续操作 }
t[i](s) 可能是对 异步生成器 (async generator) 的调用,如 next() 或 throw()。Promise.resolve(u).then(r, o); 使得代码可以顺序执行 async/await 逻辑。o(t) 返回一个新的 Promise 包装器
function o(t) { return function () { var e = this, n = arguments; return new Promise(function (o, i) { var s = t.apply(e, n); function a(t) { r(s, o, i, a, u, "next", t); } function u(t) { r(s, o, i, a, u, "throw", t); } a(void 0); }); }; }
o(t) 是一个高阶函数,返回另一个函数。Promise 并调用 t.apply(e, n),即执行原始函数 t。 a(t) 处理 next() 迭代,而 u(t) 处理 throw() 异常,确保 async/await 代码可以顺序执行。
这段代码的核心功能是将异步生成器 (async generator) 包装成 Promise,从而支持 async/await 语法。这在爬虫开发中非常有用,主要体现在以下方面:
顺序执行异步请求
async/await 让代码看起来更直观,避免回调地狱。async function crawlPages(urls) { for (const url of urls) { const data = await fetch(url).then(res => res.text()); console.log(`Fetched data from ${url}`); } }
2.处理 Promise 失败和重试
catch (c) { return void n(c); },代码可以捕获爬虫请求中的错误,如网络超时、403/404 响应等。可以结合重试逻辑来提高爬取成功率
async function fetchWithRetry(url, retries = 3) { for (let i = 0; i < retries; i++) { try { return await fetch(url).then(res => res.text()); } catch (error) { console.log(`Retry ${i + 1} for ${url}`); } } throw new Error(`Failed to fetch ${url} after ${retries} attempts`); }
3.支持爬取数据的流式处理
Promise.resolve(u).then(r, o);,这意味着它可以在数据部分获取后立即处理,而无需等待整个任务完成。async function* streamCrawl(urls) { for (const url of urls) { yield await fetch(url).then(res => res.text()); } } (async () => { for await (const pageData of streamCrawl(["url1", "url2"])) { console.log(pageData); } })();
这段代码的主要目的是将异步函数转换为基于 Promise 的执行流,它在爬虫领域的关键作用包括:
async/await 语法,使代码更加清晰这些特性使得代码适用于爬取 API、动态网页数据提取、增量爬取等应用场景。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。