JSFiddle - React, Tailwind, and code Playground

by ryanwheale

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://canjs.com/release/2.3.14/can.jquery.js"></script>
<script src="https://canjs.com/release/2.3.14/can.map.define.js"></script>
When an async getter calls the "resolver" function during the synchrouns "get" execution, extra bindings are created which cause an infinite loop. If instead you simply return the value instead of resolving it, the loop goes away.

<div id="app"></div>
<button>Login</button>

JavaScript

console.clear();
var AppState = can.Map.extend({
	userId: "000"
});
window.__APP = new AppState();

var ViewModel = can.Map.extend({
	define: {
  	regions: {
    	get: function (lastSetVal, resolver) {
      	debugger;
      	var appState = window.__APP;
        var userId = appState.attr("userId");
        setTimeout(function () {
        	debugger;
        	resolver([{ id: 123 }]);
        }, 500);
        // WHEN THIS IS CHANGED TO `return [];` THE LOOP GOES AWAY
        resolver([]);
      }
    }
  }
});

var vm = new ViewModel();
var compute = can.compute(function (ctx) {
	var regions = vm.attr("regions");
	return "<h1>(" + regions.length + ") Hello there. Open your console and click login.</h1>";
});
var render = function () {
	document.getElementById("app").innerHTML = compute();
};
compute.bind("change", render);

render();

$("button").on("click", function (ev) {
	ev.preventDefault();
	window.__APP.attr("userId", 123);
});