简体   繁体   English

ClojureScript,Figwheel,Devcards,Race Condition

[英]ClojureScript, Figwheel, Devcards, Race Condition

Here is my minimal failure case. 这是我最小的失败案例。

(ns hello
  (:require-macros [devcards.core :as dc])
  (:require [reagent.core :as r]
            [devcards.core :as dc]
            [gamma.api :as g]
            [gamma.program :as p]
            [goog.dom :as gdom]
            [goog.webgl :as ggl]))


(defn main []
  (let [canvas (.getElementById js/document "webgl")
        gl (.getContext canvas "webgl")] ;; *** THIS LINE ***
    (.clearColor gl 0.0 0.0 0.0 1.0)
    (.clear gl gl.COLOR_BUFFER_BIT)))


(dc/defcard-rg canvas-example
  [:div
   [:canvas {:width 600
             :height 600
             :id "webgl"}]])


(main)

Here's what happens when I load this up in figwheel/devcard. 这是当我在figwheel / devcard中加载它时会发生什么。

  1. First time loading page: "Cannot read property 'getContext' of null" on * THIS LINE * . 第一次加载页面:“无法在* THIS LINE *上读取属性'getContext'的null”。 This is because the devcard canvas hasn't been setup yet. 这是因为尚未设置devcard画布。

  2. If I make a pointless change and save the file, the code reloads and works fine. 如果我做了一个毫无意义的更改并保存文件,代码重新加载并正常工作。 This is because the devcard canvas HAS been setup. 这是因为已经设置了devcard canvas。

  3. It's clear this is a race condition between (a) when (main) runs and (b) when devcard's :canvas is setup. 很明显这是(a)当(主)运行和(b)devcard's:canvas设置之间的竞争条件。

  4. How do I fix this? 我该如何解决? Ideally, I want to tag something to the canvas saying "run the main function after this ..." 理想情况下,我想在画布上标记“在此之后运行主要功能......”

Okay, I figured this out. 好的,我想出来了。

The simplest solution (ie does not involve hacking devcard / reagent) is to just have a separate cljs/go thread check every 50ms to see whether the element exists, and if so, exec the function. 最简单的解决方案(即不涉及破解devcard /试剂)是每隔50ms进行一次单独的cljs / go线程检查以查看元素是否存在,如果存在,则执行该函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM