Webglcontextcreationerror event: does it fire synchronously?

Is the webglcontextcreationerror event synchronous or asynchronous? For instance,

canvas.addEventListener("webglcontextcreationerror", function() { console.log("Error"); }); var context = canvas.getContext("webgl"); console.log("After creation"); 

in case of an error

 "After creation" "Error" 

or

 "Error" "After creation" 

?

I am not sure how to make this event know the answer itself.

+3
source share
2 answers

NB . This is not an answer to one call, but only from one UA test, so it may be incorrect or at least true only for that UA, aka Chrome.


In chrome, to raise an error event, you can request 2dContext first and then webgl.

Thus, we see that this UA considers the event as synchronous.
I just find out about these right now ...

 var canvas = document.createElement('canvas') canvas.addEventListener("webglcontextcreationerror", function() { snippet.log("Error"); }); canvas.getContext('2d') canvas.getContext("webgl"); snippet.log("After creation"); 
 <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.imtqy.com/simple-snippets-console/snippet.js"></script> 
0
source

So, is there one question, why do you care about the order? getContext returns null on failure, so if you want to find out if this failed, you are done. webglcontextcreationerror Only the point is for you to understand the reason why this failed, since getContext has no way to do this. That way, you can structure your code in such a way that it doesn’t matter if it will synchronize or asynchronously

 var canvas = document.createElement('canvas') function doSomethingWithStatusMessage(e) { log("context creation error: "+ e.statusMessage); } canvas.addEventListener("webglcontextcreationerror", doSomethingWithStatusMessage); log("2d: " + canvas.getContext('2d')); log("webgl: " + canvas.getContext("webgl")); log("after creation"); function log(msg, color) { var div = document.createElement("pre"); div.appendChild(document.createTextNode(msg)); document.body.appendChild(div); } 

doSomethingWithStatus message can do anything. Suppose a dialog is displayed based on getContext .

 if (!canvas.getContext("webgl")) { g_dialog = new Dialog("can't create context", g_reason); } 

Then you might have a code like

 var g_reason = "unknown"; var g_dialog; function doSomethingWithStatusMessage(e) { if (g_dialog) { g_dialog.updateReason(e.statusMessage); } else { g_reason = g.statusMessage; } } function Dialog(msg, reason) { var div = document.createElement("div"); div.appendChild(document.createTextNode(msg)); var reasonNode = document.createTextNode(""); div.appendChild(reasonNode); updateReason(reason); function updateReason(reason) { reasonNode.nodeValue = reason; } this.updateReason = updateReason; } 

 var g_reason = "unknown"; var g_dialog; function doSomethingWithStatusMessage(e) { if (g_dialog) { g_dialog.updateReason(e.statusMessage); } else { g_reason = e.statusMessage; } } var canvas = document.createElement('canvas') canvas.addEventListener("webglcontextcreationerror", doSomethingWithStatusMessage); log("2d: " + canvas.getContext('2d')); var gl = canvas.getContext("webgl"); log("webgl: " + gl); log("after creation"); if (!gl) { new Dialog("could not create WebGL context: ", g_reason); } function log(msg, color) { var div = document.createElement("pre"); div.appendChild(document.createTextNode(msg)); document.body.appendChild(div); } function Dialog(msg, reason) { var outer = document.createElement("div"); outer.className = "dialog"; var div = document.createElement("div"); div.appendChild(document.createTextNode(msg)); var reasonNode = document.createTextNode(""); div.appendChild(reasonNode); outer.appendChild(div); updateReason(reason); document.body.appendChild(outer); outer.addEventListener('click', close); function updateReason(reason) { reasonNode.nodeValue = reason; } function close() { document.body.removeChild(outer); outer.removeEventListener('click', close); } this.close = close; this.updateReason = updateReason; } 
 .dialog { position: absolute; z-index: 2; background: rgba(0,0,0,0.8); color: red; left: 0; top: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-content: center; align-items: center; } 

If instead you want to report an error to the server, for example, just run it a few seconds later to allow the asynchronous message to arrive.

 if (!canvas.getContext("webgl")) { // give a moment for the async message to arrive setTimeout(uploadReason, 1000); } 

The rest will be easy

 var g_reason = "unknown"; function doSomethingWithStatusMessage(e) { g_reason = e.statusMessage; } function uploadReason() { .. XHR g_reason to server .. } 

Note: I will create an error in this part of the specification so that you can follow if you want.

+2
source

Source: https://habr.com/ru/post/1247337/


All Articles