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

ClojureScript中如何等待服务器响应后再执行后续调用?

解决异步请求后的时序问题

首先咱们得搞清楚为啥会出现这个情况:ajax/GET是异步执行的——你调用get-tables之后,代码会立刻往下走执行js/console.log @tables,这时候服务器的响应还没回来,tables这个atom还是初始的nil,所以第一次打印null;等你第二次点击的时候,之前的请求已经完成,atom已经被更新成服务器返回的数据,自然就能正常打印了。

要解决这个问题,核心就是等服务器响应回来、atom更新完成之后,再执行打印操作,这里给你几种常用的方案:

方案一:利用Promise链式调用

ajax/GET本身会返回一个JS Promise,我们可以直接用它的.then方法来指定请求完成后要执行的操作:

(def tables (atom nil))

(defn get-tables []
  ;; 返回ajax请求的Promise
  (ajax/GET "/tables"
    {:headers {"Accept" "application/transit+json"}
     :handler #(reset! tables (vec %))}))

(defn validateDatasource [datasource]
  ;; 等get-tables的请求完成后再打印
  (.then (get-tables)
         (fn [] (js/console.log @tables))))

方案二:使用async/await(更直观的异步写法)

如果你习惯现代JS的异步风格,可以把validateDatasource定义成async函数,用await等待请求完成:

(def tables (atom nil))

(defn get-tables []
  (ajax/GET "/tables"
    {:headers {"Accept" "application/transit+json"}
     :handler #(reset! tables (vec %))}))

(defn validateDatasource [datasource]
  (js/async function []
    ;; 等待请求完成
    (await (get-tables))
    ;; 此时atom已经被更新,打印即可
    (js/console.log @tables)))

方案三:直接把打印逻辑放到请求的handler里

如果打印操作就是这个请求完成后必须立刻做的事情,那最简单的方式就是把打印逻辑直接写在get-tables的handler里:

(def tables (atom nil))

(defn get-tables []
  (ajax/GET "/tables"
    {:headers {"Accept" "application/transit+json"}
     :handler (fn [response]
                (reset! tables (vec response))
                ;; 请求完成后立刻打印
                (js/console.log @tables))}))

(defn validateDatasource [datasource]
  (get-tables))

这几个方案都能解决你的问题,你可以根据自己的业务场景选最合适的——比如如果后续还要在请求完成后做更多操作,方案一或二更灵活;如果只是单纯打印,方案三最省事。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:24:06