You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AlamoFire无响应:基于Vapor后端的简单爬虫开发异常

问题:Vapor后端中Alamofire请求回调无响应

我正尝试基于服务端Vapor后端,使用Alamofire开发一个简单的爬虫。Alamofire似乎已正常初始化,但回调处理器未产生任何响应。相关代码如下:

import Routing
import Vapor
import Alamofire

public func routes(_ router: Router) throws {
    router.get("scrape") { req -> String in
        let stuff = Stuff(id: nil, sourcecode: "This saves to the database.")
        stuff.save(on: req)
        let q = Alamofire.request("http://sigh-fi.com/test.txt").responseString { response in
            // 这里的回调完全没触发
            print(response)
            if let data = response.result.value {
                stuff.sourcecode = data
                stuff.save(on: req)
            }
        }
        return "Started scraping..."
    }
}

解决方案

这个问题核心是Vapor路由闭包的同步特性和Alamofire异步请求的冲突,再加上线程调度的细节问题,下面一步步帮你解决:

1. 用EventLoopFuture处理异步逻辑

Vapor的路由闭包默认是同步执行的,你的代码里闭包会在Alamofire请求完成前就返回Started scraping...,后续回调操作也脱离了Vapor的异步上下文。你需要把路由返回类型改成EventLoopFuture<String>,用EventLoopPromise来包装Alamofire的异步结果:

public func routes(_ router: Router) throws {
    router.get("scrape") { req -> EventLoopFuture<String> in
        // 创建Promise管理异步结果
        let promise = req.eventLoop.makePromise(of: String.self)
        
        let stuff = Stuff(id: nil, sourcecode: "This saves to the database.")
        
        // 先等待初始数据库保存完成,再发起请求
        stuff.save(on: req).whenComplete { saveResult in
            switch saveResult {
            case .success:
                Alamofire.request("http://sigh-fi.com/test.txt").responseString { response in
                    switch response.result {
                    case .success(let data):
                        stuff.sourcecode = data
                        // 保存更新后的数据,同样等待操作完成
                        stuff.save(on: req).whenComplete { updateResult in
                            if updateResult.isSuccess {
                                promise.succeed("Scraping completed and saved!")
                            } else {
                                promise.fail(updateResult.error ?? Abort(.internalServerError))
                            }
                        }
                    case .failure(let error):
                        promise.fail(error)
                    }
                }
            case .failure(let error):
                promise.fail(error)
            }
        }
        
        // 返回Promise关联的Future
        return promise.futureResult
    }
}

2. 把回调切换到Vapor的EventLoop

Alamofire的默认回调线程可能不在Vapor的EventLoop上,直接在回调里操作数据库可能引发线程安全问题。可以把回调逻辑调度回当前请求的EventLoop:

Alamofire.request("http://sigh-fi.com/test.txt").responseString { response in
    // 切换到Vapor的EventLoop执行后续操作
    req.eventLoop.execute {
        // 这里处理response和数据库操作
    }
}

3. 添加错误调试排查问题

先在回调里打印错误信息,确认请求本身是否成功:

Alamofire.request("http://sigh-fi.com/test.txt").responseString { response in
    print("Response received: \(response)")
    if let error = response.result.error {
        print("Request error: \(error)")
    }
    // ... 其他逻辑
}

这样能快速排查是请求失败,还是回调未执行的问题。


内容的提问来源于stack exchange,提问作者Eric_WVGG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:46:29