I am trying to convert below code of AngularJS 1.6 into polymer 2.0
AngularJS
for ( int i=0; i<=10; i++ )
{
// call rest service for Rates
var rates = fxRateService.query({ids : rateIds}, function() {
//do some processing here
}
}
Polymer Code
for ( int i=0; i<=10; i++ )
{
// call rest service for Rates
this.$.rateAjax.url = 'api/v1/fxrates?ids=' + rateIds;
this.$.rateAjax.generateRequest();
}
requestEnd() {
// do processing based on the response retrieved
}
The problem is that in Polymer when FOR loop runs, the program does not run in synchronous way. If FOR loop runs 5 times, the program makes 5 calles to rest service but the Program comes to requestEnd method after all iterations of FOR loop are complete.
What I want is, it should call Rest Service, wait for the service to return and execute requestEnd method, then make second call to Rest Service as done by AngularJS code.
Can you please guide me?
If you design your "requestEnd" method as a Promise then you can do something like this:
function queryAll(i){
if(i === 10)
{
return;
// All done
}
return this.$.rateAjax.generateRequest().then(requestEnd).then(()=>{
i++;
return queryAll(i);
})
}
Related
My ASP.NET Core Web API (Linux) endpoint needs to serve a high volume of concurrent requests. If the request takes more than 200ms then it should abort and return a custom piece of JSON. The code is all awaitable. The request must always return HTTP 200 and the HTTP request timeout cannot be reduced from 30 secs to 200ms.
What is the most efficient way to accomplish what I want? Should I use a Task? Should I use Task.Wait or Task.WaitAsync? Or should the work methods run in the HTTP request thread, periodically check Stopwatch.Elapsed and throw a timeout exception?
This is my current code:
var task = Task.Factory.StartNew(async () =>
{
// Processing part 1
var result1 = await DoWorkPart1("Param1");
if (cancellationToken.IsCancellationRequested())
cancellationToken.ThrowIfCancellationRequested();
// Processing part 2
var result2 = wait DoWorkPart2(result1);
return result2;
}).Unwrap(); // Return lambda task, not outer task
// Is it better to use WaitAsync?
task.Wait(TimeSpan.FromMilliseconds(150));
if (task.IsCompleted) // Result within timeout
{
if (task.Exception == null) // Success
{
return Ok(task.Result);
}
else
{
return Ok(new FailedObject() { Reason = ReasonEnum.UnexpectedError };
}
}
else // Timeout
{
return OK(new FailedObject() { Reason = ReasonEnum.TookTooLong };
}
What is the most efficient way to accomplish what I want?
I recommend using CancellationTokens to cancel. With a very short timeout like 200ms, you might just want to create a CancellationTokenSource with that timeout and ignore the CancellationToken provided to you by ASP.NET, which handles situations like clients disconnecting early.
Should I use a Task? Should I use Task.Wait or Task.WaitAsync? Or should the work methods run in the HTTP request thread, periodically check Stopwatch.Elapsed and throw a timeout exception?
I would say none of these. Instead, pass the CancellationToken down as far as you possibly can, ideally right to the lowest-level APIs your asynchronous code is calling.
If some of those APIs ignore their cancellation tokens, or if it's possible they may complete synchronously (e.g., due to caching), then adding cancellationToken.ThrowIfCancellationRequested(); in-between steps is a good idea.
Side note: Don't use StartNew.
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200));
try
{
// Processing part 1
var result1 = await DoWorkPart1("Param1", cts.Token);
cts.Token.ThrowIfCancellationRequested();
// Processing part 2
var result2 = wait DoWorkPart2(result1, cts.Token);
return Ok(result2);
}
catch (OperationCanceledException)
{
return OK(new FailedObject() { Reason = ReasonEnum.TookTooLong };
}
catch
{
return Ok(new FailedObject() { Reason = ReasonEnum.UnexpectedError };
}
This is question about golang selenium webdriver.
Is there any function that returns only after some js code return true.
var session *webdriver.Session
...
session.waitForJs(`$('#redButton').css('color')=='red'`)
// next code should be executed only after `#redButton` becomes red
The problem is that method session.waitForJs do not exist.
I don't see any wait functions in the golang bindings to Selenium, so you'll most likely need to define your own. This is my first attempt at golang, so bear with me:
type elementCondition func(e WebElement) bool
// Function returns once timeout has expired or the element condition is true
func (e WebElement) WaitForCondition(fn elementCondition, int timeOut) {
// Loop if the element condition is not true
for i:= 0; !elementCondition(e) && i < timeOut; i++ {
time.sleep(1000)
}
}
There are two options to define the elementCondition. Your method of using Javascript looks like it could work with the ExecuteScript function documented in webdriver.go
// Inject a snippet of JavaScript into the page for execution in the
context of the currently selected frame. The executed script is
assumed to be synchronous and the result of evaluating the script is
returned to the client.
An alternative is to access the element properties through Selenium
func ButtonIsRed(WebElement e) (bool) {
return (e.GetCssProperty('color') == 'red')
}
So your code would become
var session *webdriver.Session
....
// Locate the button with a css selector
var webElement := session.FindElement(CSS_Selector, '#redButton')
// Wait for the button to be red
webElement.WaitForCondition(ButtonIsRed, 10)
I've defined some API calls in Futures that make API calls to Mashery and Stripe
val stripeFuture = Future { // api call }
val masheryFuture = Future { //api call }
For the stripeFuture -The main logic is to set the stripeCustomerId on a Client object within the onSuccess block
stripeFuture onSuccess {
//client.stripeCustomerId
}
I've wrapped up the API calls in a for-comprehension similar to the example in Futures and Promises
val apiCalls = for {
masheryInfo <- masheryFuture
stripeCustomer <- stripeFuture
}
There is a rollback if one of the API calls fail
apiCalls onFailure {
case pse: MasheryException => {
// delete stripe customer id
}
case e: StripeException => {
//delete mashery api key
}
The problem is when the call to Mashery fails 'masheryFuture', I want to rollback 'get the stripe id' from the Client object but there is a around a 1 second delay til that call finishes and it doesn't set the stripeCustomerId until it hits the onSuccess block so within the ase pse: MasheryException => { } block, client.getstripeCustomerId returns null.
Is there a way of getting around this race condition for both of the API calls
Use Future.andThen.
The doc:
Applies the side-effecting function to the result of this future, and
returns a new future with the result of this future.
This method allows one to enforce that the callbacks are executed in a
specified order.
for (f <- Future(x).andThen { y }) etc.
Update:
for (f <- Future(x) andThen {
case Success(x) => use(x)
case _ => // ignore
}) yield result
I have a question regarding the sequencing of events in the scenario where you are calling a wcf service from silverlight 3 and updating the ui on a seperate thread. Basically, I would like to know whether what I am doing is correct... Sample is as follows. This is my first post on here, so bear with me, because i am not sure how to post actual code. Sample is as follows :
//<summary>
public static void Load(string userId)
{
//Build the request.
GetUserNameRequest request =
new GetUserNameRequest { UserId = userId };
//Open the connection.
instance.serviceClient = ServiceController.UserService;
//Make the request.
instance.serviceClient.GetUserNameCompleted
+= UserService_GetUserNameCompleted;
instance.serviceClient.GetGetUserNameAsync(request);
return instance.VM;
}
/// <summary>
private static void UserService_GetUserNameCompleted(object sender, GetUserNameCompletedEventArgs e)
{
try
{
Controller.UIDispatcher.BeginInvoke(() =>
{
//Load the response.
if (e.Result != null && e.Result.Success)
{
LoadResponse(e.Result);
}
//Completed loading data.
});
}
finally
{
instance.serviceClient.GetUserNameCompleted
-= UserService_GetUserNameCompleted;
ServiceHelper.CloseService(instance.serviceClient);
}
}
So my question basically is, inside of my UI thread when I am loading the response if that throws an exception, will the "finally" block catch that ? If not, should i put another try/catch inside of the lambda where I am loading the response ?
Also, since I am executing the load on the ui thread, is it possible that the finally will execute before the UI thread is done updating ? And could as a result call the Servicehelper.CloseService() before the load has been done ?
I ask because I am having intermittent problems using this approach.
The finally block should get executed before the processing of the response inside the BeginInvoke. BeginInvoke means that the code will get executed in the next UI cycle.
Typically the best approach to this type of thing is to pull all the data you need out of the response and store it in a variable and then clean up your service code. Then make a call to BeginInvoke and update the UI using the data in the variable.
I'm trying to get this sample for AJAX to WCF working, with the following code. When viewed in FF, nothing is displayed, and when viewed in IE, the time is displayed.
I'm using IIS 7, btw.
function getTime() {
TimeService.TimeService.GetTimeFormatted("dd-mm-yyyy [hh:mm:ss]", onMethodCompleted, onMethodFailed);
}
function onMethodCompleted(results) {
$get("currentTimeLabel").innerText = results;
}
...
I've not used MS AJAX, but as far as I can tell,
function getTime() {
TimeService.TimeService.GetTimeFormatted("dd-mm-yyyy [hh:mm:ss]", onMethodCompleted, onMethodFailed);
}
That right there seems like it'll run an aync invoke on GetTimeFormatted, and pass the results on to "onMethodCompleted"..
function onMethodCompleted(results) {
$get("currentTimeLabel").innerText = getTime();
}
Will, for every time it gets invoked, re-invoke the getTime method.. So what you're doing is starting a loop of asynchronous invokes.
It seems to me (noted that I've not used ms ajax..) that you should probably have something more like..
function getTime()
{
var onComplete = function(results) { $get("currentTimeLabel").innerText = results; }
TimeService.TimeService.GetTimeFormatted("dd-mm-yyyy [hh:mm:ss]", onComplete , onMethodFailed);
}
And then invoke the getTime method when you want the results updated.