how to delay one function until another function completes? - function

I am having difficulty finding the answer to this question - I suspect because I'm probably not using the right terminology. I am using Meteor.
Here is what I am trying to accomplish:
Function A - returns the flickr userID based on userAPI and username
Function B - uses the userID generated by Function A
The problem I have is that Function B is completing before Function A has had a chance to retrieve the information from Flickr.
What is the best manner to delay Function B and somehow connect it to the successful completion of Function A?

Since Meteor is an async framework built on top of Node, you have to think a little differently then you're probably used to. One way to do this would be as follows.
var a = function(cb){
var flickerId = getFlickerId();
cb(flickerId);
};
var b = function(flickerId){
//do something with the id
};
//call it
a(b);
I'm guessing you're using some framework that gets the flicker info for you. That framework probably has a function call which takes a callback like function 'a' above.
As the callback stack grows deeper and deeper this sort of code can become confusing. Once you have mastered the above, I suggest looking into https://github.com/kriskowal/q for a cleaner solution.

Related

Conditional cases in cypress

I have a problem for writing tests for conditional cases. One of the test uses the api in 'before' (beforeAll) function to create an object, and then in test the object that was created is not shown in searching result sometimes. I was using puppeteer before. I can let the page reload until the object shows in the search result. However, there is no way for me to do the same thing. I was thinking of using cy.get and then checking the response. For instance, (cy.get('sth').then(s1 => {do something like cy.reload()})).
Then, I found out that s1 always kept the same after reload. So, I am stuck. Hope someone give me a hand to it. If the description is not clear, please the my another post below. Thanks
Im sorry but the problem is in your before function. You gotta start it only when you are done preparing your environments to run your test.
const createPerson = (params, done)=>{
cy.request({// create people here}).then(({people})=>{
done(undefined, {people});
})
}
before((done)=> {
createPerson({}, (err, {people})=>{
cy.visit('mywebsite);
login({}, done); // this should be async as well
});
})
it('search person I created by calling api', () => {
//if you data is not cached, at this point you will have the people populated in your screen.
cy.get('.search')
.type('person's name{enter}');
cy.get(':nth-child(1) > resulttable').click();
Based on what I'm gathering from your post, I think something like this may help:
cy.get('some.selector').then(elem => {
// ...
});
cy.reload();
cy.get('some.selector').then(elem => {
// run code on element after reloading...
});
If this does not answer your question, please consider making a minimal, complete and verifiable example.
My bad. I didn't explain my problem well. The problem is not in before() function. In before() function, I call post API to create persons.
Then, I will use those persons created in before() function in each of my tests.
The code would look like:
before(()=> {createPerson(); cy.visit('mywebsite); login();} )
it('search person I created by calling api', () => {
cy.get('.search')
.type('person's name{enter}');
cy.get(':nth-child(1) > resulttable').click();
Here is the problem. I can't find the person in search result since the data needs time to be passed. Then, the test fails.
So, I need reload the page (The page is searching result page) by calling
cy.reload();
However, I don't know how many reload I need to call above to let the person show up in the searching result.
The current solution I used is to cy.wait(30000). wait 30 seconds.
So, I am wondering how I am going to do right now.

node-red call node function from nodes, like call common function

I have 2 nodes, which needs to call one function - it's common place in programming.
I suppose, there is no way in node-red to call the function, except "wiring" Function nodes sequentially.
Well, I did try it, but with no success.
Please look(copy_paste) at my flow and give help:
[{"id":"d86b4b3b.0670d8","type":"inject","z":"901492e5.e9666","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":169,"y":224,"wires":[["1a6b10c8.0788cf"]]},{"id":"1a6b10c8.0788cf","type":"function","z":"901492e5.e9666","name":"func0","func":"if(msg.payload.second_call){return [null,msg];}\nelse {msg.payload[\"second_call\"] = true;\nmsg.payload[\"count\"] = 0;\nreturn [msg,null];\n}\n","outputs":"2","noerr":0,"x":350,"y":223,"wires":[["577ae7e1.0c1948"],["b2204e3f.44cef"]]},{"id":"577ae7e1.0c1948","type":"function","z":"901492e5.e9666","name":"func1","func":"msg.payload.count++;\nreturn msg;","outputs":1,"noerr":0,"x":352,"y":316,"wires":[["1a6b10c8.0788cf"]]},{"id":"4e8f3348.10ab0c","type":"debug","z":"901492e5.e9666","name":"","active":true,"console":"false","complete":"payload","x":783.5,"y":332,"wires":[]},{"id":"b2204e3f.44cef","type":"function","z":"901492e5.e9666","name":"func3","func":"msg.payload.count++;\nreturn msg;","outputs":1,"noerr":0,"x":619,"y":332,"wires":[["4e8f3348.10ab0c"]]},{"id":"5bf50c74.5376e4","type":"inject","z":"901492e5.e9666","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":160,"y":422,"wires":[["c9b5e6b.ae91818"]]},{"id":"c9b5e6b.ae91818","type":"function","z":"901492e5.e9666","name":"func10","func":"if(msg.payload.second_call){return [null,msg];}\nelse {msg.payload[\"second_call\"] = true;\nmsg.payload[\"count\"] = 0;\nreturn [msg,null];\n}\n","outputs":"2","noerr":0,"x":345,"y":422,"wires":[["f11eb781.083348"],["b2204e3f.44cef"]]},{"id":"f11eb781.083348","type":"function","z":"901492e5.e9666","name":"func11","func":"msg.payload.count+=10;\nreturn msg;","outputs":1,"noerr":0,"x":348,"y":508,"wires":[["c9b5e6b.ae91818"]]}]
There are a few of options here.
If you are going to use the "function" multiple time then you could wrap it up in a sub-flow. This means that there is one copy of the code to edit and you can chain this into flows that do not have a common end.
If you are not going to have to change the "function" at all once it's written you can add it to the functionGlobalContext in the settings.js. This will let you include it in a given function node. See the doc for how to use the context. This does mean that you can't change the code without restarting Node-RED

Lua, table containing a function

I'm using the World of warcraft API. And I want to find an EventMessageFilter. I can do so by calling
ChatFrame_GetMessageEventFilters("event")
And to do this I have to pass a chat event, in my case CHAT_MSG_WHISPER_INFORM.
So according to the API located over at
http://wowprogramming.com/docs/api/ChatFrame_GetMessageEventFilters
This function will return a table. So I named the table and tried to print its content with this code
local myNewTable = filterTable = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
for i in pairs(myNewTable) do
print(asd[i])
end
And this then prints out something like
function: 00000312498vn27842934c4
I have checked with
type(asd[i])
and it really is a function. But how can I get the content of it? How do I handle it?
I want to find an EventMessageFilter
Can you elaborate? Whose filter are you looking for and what do you intend to do with it?
it really is a function.
That's what this API does: returns a list of functions that are registered as filters for a particular message type (via ChatFrame_AddMessageEventFilter).
But how can I get the content of it?
You can't. The WoW API doesn't offer you any facilities for decompiling functions.
If your intention is to filter chat messages yourself, you don't need to call this function at all. Just call ChatFrame_AddMessageEventFilter to add your filter.
So I managed to solve my problem by removing to current filters that have been put in place by another addon and then just add my own filter. As Mud pointed out. GMEF was supposed to return functions. I now see how this makes sense. But now I have made the code to remove the functions. If you want to re-add them later on, just store them in a variable until you are done but I won't include this in my answer. I also feel like my answer is kinda half off-topic ish. But to answer my own question. It is supposed to return functions and you can't see the contents of these functions. This is the code I used to remove the functions that were put in there by another addon.
function rekkFilters()
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
for i in pairs(myFilters) do
ChatFrame_RemoveMessageEventFilter("CHAT_MSG_WHISPER_INFORM", myFilters[i])
end
end
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
rekkFilters()
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
if myFilters[1] ~= nil then
rekkFilters()
end

Nesting Asynchronous Promises in ActionScript

I have a situation where I need to perform dependent asynchronous operations. For example, check the database for data, if there is data, perform a database write (insert/update), if not continue without doing anything. I have written myself a promise based database API using promise-as3. Any database operation returns a promise that is resolved with the data of a read query, or with the Result object(s) of a write query. I do the following to nest promises and create one point of resolution or rejection for the entire 'initialize' operation.
public function initializeTable():Promise
{
var dfd:Deferred = new Deferred();
select("SELECT * FROM table").then(tableDefaults).then(resolveDeferred(dfd)).otherwise(errorHandler(dfd));
return dfd.promise;
}
public function tableDefaults(data:Array):Promise
{
if(!data || !data.length)
{
//defaultParams is an Object of table default fields/values.
return insert("table", defaultParams);
} else
{
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
}
}
public function resolveDeferred(deferred:Deferred):Function
{
return function resolver(value:*=null):void
{
deferred.resolve(value);
}
}
public function rejectDeferred(deferred:Deferred):Function
{
return function rejector(reason:*=null):void
{
deferred.reject(reason);
}
}
My main questions:
Are there any performance issues that will arise from this? Memory leaks etc.? I've read that function variables perform poorly, but I don't see another way to nest operations so logically.
Would it be better to have say a global resolved instance that is created and resolved only once, but returned whenever we need an 'empty' promise?
EDIT:
I'm removing question 3 (Is there a better way to do this??), as it seems to be leading to opinions on the nature of promises in asynchronous programming. I meant better in the scope of promises, not asynchronicity in general. Assume you have to use this promise based API for the sake of the question.
I usually don't write those kind of opinion based answers, but here it's pretty important. Promises in AS3 = THE ROOTS OF ALL EVIL :) And I'll explain you why..
First, as BotMaster said - it's weakly typed. What this means is that you don't use AS3 properly. And the only reason this is possible is because of backwards compatibility. The true here is, that Adobe have spent thousands of times so that they can turn AS3 into strongly type OOP language. Don't stray away from that.
The second point is that Promises, at first place, are created so that poor developers can actually start doing some job in JavaScript. This is not a new design pattern or something. Actually, it has no real benefits if you know how to structure your code properly. The thing that Promises help the most, is avoiding the so called Wall of Hell. But there are other ways to fix this in a natural manner (the very very basic thing is not to write functions within functions, but on the same level, and simply check the passed result).
The most important here is the nature of Promises. Very few people know what they actually do behind the scenes. Because of the nature of JavaScript (and ECMA script at all), there is no real way to tell if a function completed properly or not. If you return false / null / undefined - they are all regular return values. The only way they could actually say "this operation failed" is by throwing an error. So every promisified method, can potentially throw an error. And each error must be handled, or otherwise your code can stop working properly. What this means, is that every single action inside Promise is within try-catch block! Every time you do absolutely basic stuff, you wrap it in try-catch. Even this block of yours:
else
{
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
}
In a "regular" way, you would simply use else { return null }. But now, you create tons of objects, resolvers, rejectors, and finally - you try-catch this block.
I cannot stress more on this, but I think you are getting the point. Try-catch is extremely slow! I understand that this is not a big problem in such a simple case like the one I just mentioned, but imagine you are doing it more and on more heavy methods. You are just doing extremely slow operations, for what? Because you can write lame code and just enjoy it..
The last thing to say - there are plenty of ways to use asynchronous operations and make them work one after another. Just by googling as3 function queue I found a few. Not to say that the event-based system is so flexible, and there are even alternatives to it (using callbacks). You've got it all in your hands, and you turn to something that is created because lacking proper ways to do it otherwise.
So my sincere advise as a person worked with Flash for a decade, doing casino games in big teams, would be - don't ever try using promises in AS3. Good luck!
var dfd:Deferred = new Deferred();
select("SELECT * FROM table").then(tableDefaults).then(resolveDeferred(dfd)).otherwise(errorHandler(dfd));
return dfd.promise;
This is the The Forgotten Promise antipattern. It can instead be written as:
return select("SELECT * FROM table").then(tableDefaults);
This removes the need for the resolveDeferred and rejectDeferred functions.
var resolved:Deferred = new Deferred();
resolved.resolve(null);
return resolved.promise;
I would either extract this to another function, or use Promise.when(null). A global instance wouldn't work because it would mean than the result handlers from one call can be called for a different one.

When is passing a subprogram as a parameter necessary

I've been reading a Concepts of Programming Languages by Robert W. Sebesta and in chapter 9 there is a brief section on passing a SubProgram to a function as a parameter. The section on this is extremely brief, about 1.5 pages, and the only explanation to its application is:
When a subprogram must sample some mathematical function. Such as a Subprogram that does numerical integration by estimating the area under a graph of a function by sampling the function at a number of different points. Such a Subprogram should be usable everywhere.
This is completely off from anything I have ever learned. If I were to approach this problem in my own way I would create a function object and create a function that accomplishes the above and accepts function objects.
I have no clue why this is a design issue for languages because I have no idea where I would ever use this. A quick search hasn't made this any clearer for me.
Apparently you can accomplish this in C and C++ by utilizing pointers. Languages that allow nested Subprograms such as JavaScript allow you do do this in 3 separate ways:
function sub1() {
var x;
function sub2() {
alert( x ); //Creates a dialog box with the value of x
};
function sub3() {
var x;
x = 3;
sub4( sub2 ); //*shallow binding* the environment of the
//call statement that enacts the passed
//subprogram
};
function sub4( subx ) {
var x;
x = 4;
subx();
};
x=1;
sub3();
};
I'd appreciate any insight offered.
Being able to pass "methods" is very useful for a variety of reasons. Among them:
Code which is performing a complicated operation might wish to provide a means of either notifying a user of its progress or allowing the user to cancel it. Having the code for the complicated operation has to do those actions itself will both add complexity to it and also cause ugliness if it's invoked from code which uses a different style of progress bar or "Cancel" button. By contrast, having the caller supply an UpdateStatusAndCheckCancel() method means that the caller can supply a method which will update whatever style of progress bar and cancellation method the caller wants to use.
Being able to store methods within a table can greatly simplify code that needs to export objects to a file and later import them again. Rather than needing to have code say
if (ObjectType == "Square")
AddObject(new Square(ObjectParams));
else if (ObjectType == "Circle")
AddObject(new Circle(ObjectParams));`
etc. for every kind of object
code can say something like
if (ObjectCreators.TryGetValue(ObjectType, out factory))
AddObject(factory(ObjectParams));
to handle all kinds of object whose creation methods have been added to ObjectCreators.
Sometimes it's desirable to be able to handle events that may occur at some unknown time in the future; the author of code which knows when those events occur might have no clue about what things are supposed to happen then. Allowing the person who wants the action to happen to give a method to the code which will know when it happens allows for that code to perform the action at the right time without having to know what it should do.
The first situation represents a special case of callback where the function which is given the method is expected to only use it before it returns. The second situation is an example of what's sometimes referred to as a "factory pattern" or "dependency injection" [though those terms are useful in some broader contexts as well]. The third case is commonly handled using constructs which frameworks refer to as events, or else with an "observer" pattern [the observer asks the observable object to notify it when something happens].