First, please excuse my bad English. I'm not use to write in English.
I'm using Node.js and i have variables that sometimes get their value from async functions and sometimes by direct assignment (ex:
async(function(data) {
var x= data.something
}; or x = 5;)
the problem is that later on the have shared code which forces me to duplicate the code.
in syncronius scripting i usually do an if.. else statement to seperate the cases and assign. ex:
if(boolivar){
var x = niceFunc();
}
else {
var x = 5;
}
coolFunc(x);
now days im forced to to this:
if(boolivar){
niceFUnc(function(X){
coolFunc(X);
}
}
else{
var x = 5;
coolFunc(X);
}
does someone has an idea how to solve my problem?
I thought about forcing the async function to be sync but:
a. i dont know how
b. it kind of ruins the whole point
I would do it essentially as you have, except that I would abstract the sync/async calls so that it doesn't make any difference to the code that's using it what's really happening behind the scenes (ignore the bad function names; I have no idea what your code does):
function doNiceFunc(boolivar, callback) {
if (boolivar) {
niceFUnc(function(x) {
callback(x);
});
} else {
callback(5);
}
}
Now doNiceFunc appears the same in both cases from the outside:
doNiceFunc(boolivar, function(x) {
coolFunc(x);
});
I've used this exact pattern in a library that retrieved data that was sometimes immediately available and other times had to be retrieved from the network. The users of this library didn't have to care which was the case at any given time, because the call looked the same in both situations.
I tend to use this lib node-sync
var sync = require('sync');
sync(function(){
var result = query.sync(query, params);
// result can be used immediately
})
Related
I am trying to place retrieved data into a string or possibly an array, and be able to print it out onto a page. This is what I have so far but it doesnt work. Can anyone please tell me how to place the node.data into a string or array form?
`function neww(node) {
if (node.nodeType==Node.TEXT_NODE) {
var a=node.data;
document.getElementById("demo").innerHTML =a;
}}`
Is there a reason you're not assigning it to a var on window? (maybe you don't want a global var?)
`<script>window.INITIAL_STATE = ${JSON.stringify(initialState)}</script>`
It is difficult to answer this accurately. You didn't provide this function's context.
As I see it, your function should work fine. Other parts of your code must be breaking it.
My first guess -- you're calling this function before the page loads. That is, you're trying to insert text into an element. However, that element hasn't even been created yet.
If that is the case (you didn't provide context, so I don't know), then you should use the window.onload function. This would ensure that all elements load before attempting to manipulate them.
Here is an example:
function insertNodeTextIntoDemoElement(node) {
if (node.nodeType === Node.TEXT_NODE) {
const nodeText = node.data;
const demoElement = document.getElementById('demo');
demoDiv.textContent = nodeText;
}
}
window.onload = function () {
// Other code...
const exampleNode = document.createTextNode('Hello World!');
insertNodeTextIntoDemoElement(exampleNode);
// Other code...
};
This is the best answer I can provide, given your limited information. If you could show more of your program/give more information, I could provide a better answer.
I've been looking through various tutorials on rayCasting with Box2D, but I haven't seen any clear examples. I was hoping someone familiar with box2dweb would be able to give a clear example of how one would go about setting up a simple function that would end up looking something like this:
var myRayCastFunction = function(p1,p2,maxFraction){
//Code here
}
The idea being that it would be usable like this:
var retVal = myRayCastFunction(p1,p2,maxFraction)
var fixture = retVal.fixture
var point = retVal.point
var normal = retVal.normal
var fraction = retVal.fraction
(in this case, I'm simply returning 1 intersection, say the nearest one, but would want to know how to make a similar one where retVel is a list of these outputs for each intersection)
I've been trying to understand all of the details of how RayCasting works in box2D, and I understand that this requires making a custom callback function (I think?), but I never figured out where that function needs to be placed, and what IT should be as well.
I started to answer this question because I happened to be about to add raycasting to my current project, and I realized there were actually some bugs in box2dweb that needed to be fixed before I could get it done. I'll link to the details instead of cluttering up this post:
http://www.iforce2d.net/box2dweb-fixes.txt
Here is how I've used the raycast callback successfully. Declare your callback class and give it a ReportFixture function:
var RaycastCallback = function() {
this.m_hit = false;
}
RaycastCallback.prototype.ReportFixture = function(fixture,point,normal,fraction) {
if ( ... not interested in this fixture ... )
return -1;
this.m_hit = true;
this.m_point = point;
this.m_normal = normal;
return fraction;
};
Now make an instance of that to pass to the worlds RayCast function:
var rayStart = ...;
var rayEnd = ...;
var callback = new RaycastCallback();
world.RayCast(callback, rayStart, rayEnd);
if ( callback.m_hit ) {
... use callback.m_point etc ...
}
I'm reading the Google Drive Realtime API documentation on Building a Collaborative Data Model.
I really like the way gapi.drive.realtime.databinding.bindString behaves. It doesn't mess up your cursor placement when multiple people are typing in the same text box. But it requires that you pass it a CollaborativeString.
But if you register a custom type, you have to use gapi.drive.realtime.custom.collaborativeField no matter what type of field you are defining, and you can't pass one of these to bindString. In fact, the collaborativeField type does not appear to be documented anywhere, and inspecting it in the console shows that it has no methods. That means there's no registerReference method, which CollaborativeString uses to keep track of cursor positions.
How frustrating. So I guess I have to work around it. I see a few options:
Ignore the fact that the cursor gets messed up during collaboration
Use a CollaborativeMap instead of a custom type, and wrap it with my custom type at runtime
Probably going to do option 2.
I think you misunderstand how this site works, the onus is not on other people to show you how to do something - you're asking other people to take time from their day and help you.
That being said, taking a quick look at the page that you linked shows that what you want to do is not only possible but quite straightforward and compatible with bindString. Stealing from the example code from that page:
// Call this function before calling gapi.drive.realtime.load
function registerCustomTypes()
{
var Book = function () { };
function initializeBook()
{
var model = gapi.drive.realtime.custom.getModel(this);
this.reviews = model.createList();
this.content = model.createString();
}
gapi.drive.realtime.custom.registerType(Book, 'Book');
Book.prototype.title = gapi.drive.realtime.custom.collaborativeField('title');
Book.prototype.author = gapi.drive.realtime.custom.collaborativeField('author');
Book.prototype.isbn = gapi.drive.realtime.custom.collaborativeField('isbn');
Book.prototype.isCheckedOut = gapi.drive.realtime.custom.collaborativeField('isCheckedOut');
Book.prototype.reviews = gapi.drive.realtime.custom.collaborativeField('reviews');
Book.prototype.content = gapi.drive.realtime.custom.collaborativeField('content');
gapi.drive.realtime.custom.setInitializer(Book, initializeBook);
}
and
// Pass this as the 2nd param to your gapi.drive.realtime.load call
function onDocLoaded(doc)
{
var docModel = doc.getModel();
var docRoot = docModel.getRoot();
setTimeout(function ()
{
var book = docModel.create('Book');
book.title = 'Moby Dick';
book.author = 'Melville, Herman';
book.isbn = '978-1470178192';
book.isCheckedOut = false;
book.content.setText("Call me Ishmael. Some years ago - never mind how long precisely - having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.");
docRoot.set('tbook', book);
debugger;
}, 0);
}
Good luck and have fun with the Realtime API - it's a lot of fun to play with.
I know this question and answer are getting old, but for reference's sake, just the last part of Grant Watters' very good answer, the onDocLoaded routine, is rather misleading. That function as written, is more suited for the 3rd parameter to the gapi.drive.realtime.load call, the onInitializeModel callback.
The 2nd parameter is called every time the Doc is loaded. You wouldn't normally add the same object over and over as the above routine would... Instead, you would normally set up your event handling, your dataBinds etc. This version might clarify somewhat:
// Pass this as the 2nd param to your gapi.drive.realtime.load call
function onDocLoaded(doc)
{
var docModel = doc.getModel();
var docRoot = docModel.getRoot();
var text = doc.getModel().getRoot().get("text");
// Add an event listener...
text.addEventListener(gapi.drive.realtime.EventType.TEXT_INSERTED, onStringChanged);
// ...and/or bind to collaborative objects:
var textArea = document.getElementById('textArea1')
textBinding = gapi.drive.realtime.databinding.bindString(text, textArea);
etc...
}
Not incidentally, bindString returns the binding object, which is needed to "unbind" later, preventing an AlreadyBound error or other unexpected behavior when the next Doc is loaded. Do something like this:
function onDocLoaded(doc)
{
// Clear any previous bindings etc:
if (textBinding) { textBinding.unbind() };
textBinding = null;
etc...
Long ago I've read a lot about javascript coding conventions, and one of the things I wanted to decide was the better way of declaring functions. I finally somehow stuck with the
var func_name = function(){};
version, because it seemed more useful in certain scenarios, but I wasn't really able to find things that wouldn't work the same way between them until now.
I was writing a function that should've returned a new function to be used in a setTimeout command, but I couldn't get it to work properly, and after I reduced the whole thing to this test code:
var test = new function(x) {
return function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
};
I happened to try if writing it in the
function func_name(){}
style would help (because I really couldn't see the problem with my code), and interestingly enough this code
function test(x) {
return function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
}
seems to be working perfectly.
A weird thing to discover was that after playing a bit around in the console I realized that the first one effectively becomes the function it should generate.
I tested it in Chrome and Firefox too, and I also tried using it this way
var test = new function(x) {
var result = function() {
if (x % 2 == 1) {
console.log('a');
}
else {
console.log('b');
}
x++;
};
return result;
};
but I wasn't able to make it work.
I would be interested in any explanation to this phenomenon and also it fascinates me if there is a way to make this type of function declaration capable of producing functions.
Thanks in advance!
Edit: I don't know how, but somehow that new keyword got there by mistake :D (and even into the third version by that stupid copy-paste laziness of mine.....)
I'm still interested in knowing why the function becomes what it should create though!
Why are you using new? Remove that and it should be fine IMO.
You are using it as if it were a Construtor.
Though valid, can create issues as your current issue.
I'm writing modular JavaScript and I have a certain function that does a whole lotta processing, viz. Draw 2 canvases, update a lot of variables and store object references. Now I want to execute another function which uses some of the variables updated above.
Something like this:
Paint canvases - Store image dimensions in variables (and a lot of other stuff)
Use those dimensions to do some math and geometry, update the canvases again! I can't do this math in the first function, as it is a common utility function I use to paint canvas, everywhere in my code.
If I inject a setTimeout in my code for 10 seconds, everything works fine, but without it, the second instruction above does not find the updated variables and hence fails.
Any way to work around this? Meaning, I want to execute the second instruction ONLY after some of the required variables are set. Synchronous execution, I say.
Note: I can't post any code here (or anywhere for that matter) as it is not allowed in my workplace!
For cases like this, I suggest to use jQuery and custom events. Simply post an event when the first function has finished updating the canvas. The second function (and anything else) can listen to these events and do whatever they want.
Pro:
No coupling
Individual parts are easy to test
Extensible
Con:
Needs jQuery or you'll need to extract the event handling code.
You could use getters and setters to watch for you for a given condition.
In the setter you can do some computations, check if some conditions are met
and update if required.
Just to give you an idea :
// updateFunc is the function called whenever a property changes
// and all conditions are met for an update.
// newProp1,2,3 are the new values for prop1,2,3
function MyStorageClass(updateFunc, newProp1, newProp2, newProp3 ) {
this.updateFunc = updateFunc;
this.prop1 = newProp1 ;
this.prop2 = newProp2 ;
this.prop3 = newProp3 ;
}
var MSCProto = MyStorageClass.prototype;
// update is needed if all properties are >0
MSCProto.checkUpdateRequired = function() {
return ( ( this.prop1 > 0 ) && (this.prop2 > 0) && (this.prop3 > 0) )
}
Object.defineProperty(MSCProto, 'prop1', {
get : function() { retrurn this._prop1},
set : function(x) { this._prop1 = x;
// and some other computations if need be
if (this.checkUpdateRequired()) this.updateFunc(); } };
Object.defineProperty(MSCProto, 'prop2', {
get : function() { retrurn this._prop2},
set : function(x) { this._prop2 = x;
// and some other computations if need be
if (this.checkUpdateRequired()) this.updateFunc(); } };
Object.defineProperty(MSCProto, 'prop3', {
get : function() { retrurn this._prop3},
set : function(x) { this._prop3 = x;
// and some other computations if need be
if (this.checkUpdateRequired()) this.updateFunc(); } };