Archie  Clayton

Archie Clayton

1588488960

How to use the JavaScript Equivalent of Sleep, Wait, Delay, and Pause

JavaScript is the language of web. JS hasn’t been the same since ES5 was released. More and more ideas and features are being ported from different languages and being integrated in JavaScript. One such feature is Promises, which is probably the most widely used thing in JavaScript after ES5 was released.

But one of the things which JavaScript miss is the way to “pause” execution for a while and resume it later. In this post, I’ll discuss how you can achieve that and what it really means to “pause” or “sleep” in JavaScript. Spoiler: JavaScript never really “pauses”

TL;DR

Here’s the copy-pasta code which would do the job:

/**
 * 
 * @param duration Enter duration in seconds
 */
function sleep(duration) {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve()
		}, duration * 1000)
	})
}

But what is really happening here?

setTimeout and the fake Promises

Let’s see a quick example using the above snippet (we’ll discuss what’s happening in it later)

async function performBatchActions() {
	// perform an API call
	await performAPIRequest()

	// sleep for 5 seconds
	await sleep(5)

	// perform an API call again
	await performAPIRequest()
}

This function performBatchActions, when called, would simply execute the performAPIRequest function, wait about 5 seconds, and then call the same function again. Note how I wrote about 5 seconds, and not 5 seconds.

A strong note to put out here, the above code does not guarantee a perfect sleep. It means that if you specify duration to be, say 1 second, JavaScript does not guarantee that it would start running the code after the sleep exactly after 1 second. Why? You may ask. Unfortunately, that’s because timers work in JavaScript, and in general, event loop. However, JavaScript absolutely guarantees that the piece of code after the sleep would never execute before the said time, so we don’t really have a full indeterminate situation, just a partial one, and in most cases, within a margin of a few milliseconds only.

JavaScript is single threaded

A single thread means JavaScript process cannot really go out of the way at all. It has to do all the things - from event listeners, to HTTP callbacks, on the same main thread. And when one thing is executing, another one cannot execute. Consider a webpage in which you have multiple buttons and you run the code above to simulate a sleep for lets say 10 seconds. What do you expect would happen?

Nothing at all. Your webpage would work just fine, your buttons would be responsive, and once the 10 second sleep is done, the code next to it would execute. So it’s evident that JavaScript did not really block the whole main thread because if it did that, your webpage should have frozen and the buttons should have become non-clickable. So how did JavaScript actually pause a single thread, without ever really pausing it?

Meet the Event Loop

Unlike other languages, JavaScript doesn’t just keep on executing code in a linear fashion from top to bottom. It is an asynchronous event driven language with tons of magic in the form of event loop. Event loop splits your code in synchronous and certain events - like timers and HTTP requests. Precisely speaking, there are two queues - task queue and microtask queue. Whenever you run JS, and there’s an asynchronous thing (like a mouseclick event, or a promise) JavaScript throws it in the task queue (or microtask queue) and keeps executing. When it completes a “single tick” - it checks if task queues and microtask queue has some work for it. If yes, then it’ll execute the callback/perform an action.

I would really recommend anyone interested in deep working of event loop to watch this video:

Conclusion

You came here for a simple sleep instruction in JavaScript, ended up learning about one of the core things in JavaScript - event loop! Amazing, isn’t it?

Originally published by Mehul Mohan at https://www.freecodecamp.org

#javascript #web-development

What is GEEK

Buddha Community

How to use the JavaScript Equivalent of Sleep, Wait, Delay, and Pause
Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

CSS Boss

CSS Boss

1606912089

How to create a calculator using javascript - Pure JS tutorials |Web Tutorials

In this video I will tell you How to create a calculator using javascript very easily.

#how to build a simple calculator in javascript #how to create simple calculator using javascript #javascript calculator tutorial #javascript birthday calculator #calculator using javascript and html

Nat  Grady

Nat Grady

1670062320

How to Use Zapier with MongoDB

I’m a huge fan of automation when the scenario allows for it. Maybe you need to keep track of guest information when they RSVP to your event, or maybe you need to monitor and react to feeds of data. These are two of many possible scenarios where you probably wouldn’t want to do things manually.

There are quite a few tools that are designed to automate your life. Some of the popular tools include IFTTT, Zapier, and Automate. The idea behind these services is that given a trigger, you can do a series of events.

In this tutorial, we’re going to see how to collect Twitter data with Zapier, store it in MongoDB using a Realm webhook function, and then run aggregations on it using the MongoDB query language (MQL).

The Requirements

There are a few requirements that must be met prior to starting this tutorial:

  • A paid tier of Zapier with access to premium automations
  • A properly configured MongoDB Atlas cluster
  • A Twitter account

There is a Zapier free tier, but because we plan to use webhooks, which are premium in Zapier, a paid account is necessary. To consume data from Twitter in Zapier, a Twitter account is necessary, even if we plan to consume data that isn’t related to our account. This data will be stored in MongoDB, so a cluster with properly configured IP access and user permissions is required.

You can get started with MongoDB Atlas by launching a free M0 cluster, no credit card required.

While not necessary to create a database and collection prior to use, we’ll be using a zapier database and a tweets collection throughout the scope of this tutorial.

Understanding the Twitter Data Model Within Zapier

Since the plan is to store tweets from Twitter within MongoDB and then create queries to make sense of it, we should probably get an understanding of the data prior to trying to work with it.

We’ll be using the “Search Mention” functionality within Zapier for Twitter. Essentially, it allows us to provide a Twitter query and trigger an automation when the data is found. More on that soon.

As a result, we’ll end up with the following raw data:

{
    "created_at": "Tue Feb 02 20:31:58 +0000 2021",
    "id": "1356701917603238000",
    "id_str": "1356701917603237888",
    "full_text": "In case anyone is interested in learning about how to work with streaming data using Node.js, I wrote a tutorial about it on the @MongoDB Developer Hub. https://t.co/Dxt80lD8xj #javascript",
    "truncated": false,
    "display_text_range": [0, 188],
    "metadata": {
        "iso_language_code": "en",
        "result_type": "recent"
    },
    "source": "<a href='https://about.twitter.com/products/tweetdeck' rel='nofollow'>TweetDeck</a>",
    "in_reply_to_status_id": null,
    "in_reply_to_status_id_str": null,
    "in_reply_to_user_id": null,
    "in_reply_to_user_id_str": null,
    "in_reply_to_screen_name": null,
    "user": {
        "id": "227546834",
        "id_str": "227546834",
        "name": "Nic Raboy",
        "screen_name": "nraboy",
        "location": "Tracy, CA",
        "description": "Advocate of modern web and mobile development technologies. I write tutorials and speak at events to make app development easier to understand. I work @MongoDB.",
        "url": "https://t.co/mRqzaKrmvm",
        "entities": {
            "url": {
                "urls": [
                    {
                        "url": "https://t.co/mRqzaKrmvm",
                        "expanded_url": "https://www.thepolyglotdeveloper.com",
                        "display_url": "thepolyglotdeveloper.com",
                        "indices": [0, 23]
                    }
                ]
            },
            "description": {
                "urls": ""
            }
        },
        "protected": false,
        "followers_count": 4599,
        "friends_count": 551,
        "listed_count": 265,
        "created_at": "Fri Dec 17 03:33:03 +0000 2010",
        "favourites_count": 4550,
        "verified": false
    },
    "lang": "en",
    "url": "https://twitter.com/227546834/status/1356701917603237888",
    "text": "In case anyone is interested in learning about how to work with streaming data using Node.js, I wrote a tutorial about it on the @MongoDB Developer Hub. https://t.co/Dxt80lD8xj #javascript"
}

The data we have access to is probably more than we need. However, it really depends on what you’re interested in. For this example, we’ll be storing the following within MongoDB:

{
    "created_at": "Tue Feb 02 20:31:58 +0000 2021",
    "user": {
        "screen_name": "nraboy",
        "location": "Tracy, CA",
        "followers_count": 4599,
        "friends_count": 551
    },
    "text": "In case anyone is interested in learning about how to work with streaming data using Node.js, I wrote a tutorial about it on the @MongoDB Developer Hub. https://t.co/Dxt80lD8xj #javascript"
}

Without getting too far ahead of ourselves, our analysis will be based off the followers_count and the location of the user. We want to be able to make sense of where our users are and give priority to users that meet a certain followers threshold.

Developing a Webhook Function for Storing Tweet Information with MongoDB Realm and JavaScript

Before we start connecting Zapier and MongoDB, we need to develop the middleware that will be responsible for receiving tweet data from Zapier.

Remember, you’ll need to have a properly configured MongoDB Atlas cluster.

We need to create a Realm application. Within the MongoDB Atlas dashboard, click the Realm tab.

MongoDB Realm Applications

For simplicity, we’re going to want to create a new application. Click the Create a New App button and proceed to fill in the information about your application.

From the Realm Dashboard, click the 3rd Party Services tab.

Realm Dashboard 3rd Party Services

We’re going to want to create an HTTP service. The name doesn’t matter, but it might make sense to name it Twitter based on what we’re planning to do.

Because we plan to work with tweet data, it makes sense to call our webhook function tweet, but the name doesn’t truly matter.

Realm Tweet Webhook

With the exception of the HTTP Method, the defaults are fine for this webhook. We want the method to be POST because we plan to create data with this particular webhook function. Make note of the Webhook URL because it will be used when we connect Zapier.

The next step is to open the Function Editor so we can add some logic behind this function. Add the following JavaScript code:

exports = function (payload, response) {

    const tweet = EJSON.parse(payload.body.text());

    const collection = context.services.get("mongodb-atlas").db("zapier").collection("tweets");

    return collection.insertOne(tweet);

};

In the above code, we are taking the request payload, getting a handle to the tweets collection within the zapier database, and then doing an insert operation to store the data in the payload.

There are a few things to note in the above code:

  1. We are not validating the data being sent in the request payload. In a realistic scenario, you’d probably want some kind of validation logic in place to be sure about what you’re storing.
  2. We are not authenticating the user sending the data. In this example, we’re trusting that only Zapier knows about our URL.
  3. We aren’t doing any error handling.

When we call our function, a new document should be created within MongoDB.

By default, the function will not deploy when saving. After saving, make sure to review and deploy the changes through the notification at the top of the browser window.

Creating a “Zap” in Zapier to Connect Twitter to MongoDB

So, we know the data we’ll be working with and we have a MongoDB Realm webhook function that is ready for receiving data. Now, we need to bring everything together with Zapier.

For clarity, new Twitter matches will be our trigger in Zapier, and the webhook function will be our event.

Within Zapier, choose to create a new “Zap,” which is an automation. The trigger needs to be a Search Mention in Twitter, which means that when a new Tweet is detected using a search query, our events happen.

Zapier Twitter Search Mention

For this example, we’re going to use the following Twitter search query:

url:developer.mongodb.com -filter:retweets filter:safe lang:en -from:mongodb -from:realm

The above query says that we are looking for tweets that include a URL to developer.mongodb.com. The URL doesn’t need to match exactly as long as the domain matches. The query also says that we aren’t interested in retweets. We only want original tweets, they have to be in English, and they have to be detected as safe for work.

In addition to the mentioned search criteria, we are also excluding tweets that originate from one of the MongoDB accounts.

In theory, the above search query could be used to see what people are saying about the MongoDB Developer Hub.

With the trigger in place, we need to identify the next stage of the automation pipeline. The next stage is taking the data from the trigger and sending it to our Realm webhook function.

Zapier to Realm Webhook

As the event, make sure to choose Webhooks by Zapier and specify a POST request. From here, you’ll be prompted to enter your Realm webhook URL and the method, which should be POST. Realm is expecting the payload to be JSON, so it is important to select JSON within Zapier.

We have the option to choose which data from the previous automation stage to pass to our webhook. Select the fields you’re interested in and save your automation.

The data I chose to send looks like this:

{
    "created_at": "Tue Feb 02 20:31:58 +0000 2021",
    "username": "nraboy",
    "location": "Tracy, CA",
    "follower_count": "4599",
    "following_count": "551",
    "message": "In case anyone is interested in learning about how to work with streaming data using Node.js, I wrote a tutorial about it on the @MongoDB Developer Hub. https://t.co/Dxt80lD8xj #javascript"
}

The fields do not match the original fields brought in by Twitter. It is because I chose to map them to what made sense for me.

When deploying the Zap, anytime a tweet is found that matches our query, it will be saved into our MongoDB cluster.

Analyzing the Twitter Data in MongoDB with an Aggregation Pipeline

With tweet data populating in MongoDB, it’s time to start querying it to make sense of it. In this fictional example, we want to know what people are saying about our Developer Hub and how popular these individuals are.

To do this, we’re going to want to make use of an aggregation pipeline within MongoDB.

Take the following, for example:

[
    {
        "$addFields": {
            "follower_count": {
                "$toInt": "$follower_count"
            },
            "following_count": {
                "$toInt": "$following_count"
            }
        }
    }, {
        "$match": {
            "follower_count": {
                "$gt": 1000
            }
        }
    }, {
        "$group": {
            "_id": {
                "location": "$location"
            },
            "location": {
                "$sum": 1
            }
        }
    }
]

There are three stages in the above aggregation pipeline.

We want to understand the follower data for the individual who made the tweet, but that data comes into MongoDB as a string rather than an integer. The first stage of the pipeline takes the follower_count and following_count fields and converts them from string to integer. In reality, we are using $addFields to create new fields, but because they have the same name as existing fields, the existing fields are replaced.

The next stage is where we want to identify people with more than 1,000 followers as a person of interest. While people with fewer followers might be saying great things, in this example, we don’t care.

After we’ve filtered out people by their follower count, we do a group based on their location. It might be valuable for us to know where in the world people are talking about MongoDB. We might want to know where our target audience exists.

The aggregation pipeline we chose to use can be executed with any of the MongoDB drivers, through the MongoDB Atlas dashboard, or through the CLI.

Conclusion

You just saw how to use Zapier with MongoDB to automate certain tasks and store the results as documents within the NoSQL database. In this example, we chose to store Twitter data that matched certain criteria, later to be analyzed with an aggregation pipeline. The automations and analysis options that you can do are quite limitless.

If you enjoyed this tutorial and want to get engaged with more content and like-minded developers, check out the MongoDB Community.

This content first appeared on MongoDB.

Original article source at: https://www.thepolyglotdeveloper.com/

#mongodb #zapier 

Archie  Clayton

Archie Clayton

1588488960

How to use the JavaScript Equivalent of Sleep, Wait, Delay, and Pause

JavaScript is the language of web. JS hasn’t been the same since ES5 was released. More and more ideas and features are being ported from different languages and being integrated in JavaScript. One such feature is Promises, which is probably the most widely used thing in JavaScript after ES5 was released.

But one of the things which JavaScript miss is the way to “pause” execution for a while and resume it later. In this post, I’ll discuss how you can achieve that and what it really means to “pause” or “sleep” in JavaScript. Spoiler: JavaScript never really “pauses”

TL;DR

Here’s the copy-pasta code which would do the job:

/**
 * 
 * @param duration Enter duration in seconds
 */
function sleep(duration) {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve()
		}, duration * 1000)
	})
}

But what is really happening here?

setTimeout and the fake Promises

Let’s see a quick example using the above snippet (we’ll discuss what’s happening in it later)

async function performBatchActions() {
	// perform an API call
	await performAPIRequest()

	// sleep for 5 seconds
	await sleep(5)

	// perform an API call again
	await performAPIRequest()
}

This function performBatchActions, when called, would simply execute the performAPIRequest function, wait about 5 seconds, and then call the same function again. Note how I wrote about 5 seconds, and not 5 seconds.

A strong note to put out here, the above code does not guarantee a perfect sleep. It means that if you specify duration to be, say 1 second, JavaScript does not guarantee that it would start running the code after the sleep exactly after 1 second. Why? You may ask. Unfortunately, that’s because timers work in JavaScript, and in general, event loop. However, JavaScript absolutely guarantees that the piece of code after the sleep would never execute before the said time, so we don’t really have a full indeterminate situation, just a partial one, and in most cases, within a margin of a few milliseconds only.

JavaScript is single threaded

A single thread means JavaScript process cannot really go out of the way at all. It has to do all the things - from event listeners, to HTTP callbacks, on the same main thread. And when one thing is executing, another one cannot execute. Consider a webpage in which you have multiple buttons and you run the code above to simulate a sleep for lets say 10 seconds. What do you expect would happen?

Nothing at all. Your webpage would work just fine, your buttons would be responsive, and once the 10 second sleep is done, the code next to it would execute. So it’s evident that JavaScript did not really block the whole main thread because if it did that, your webpage should have frozen and the buttons should have become non-clickable. So how did JavaScript actually pause a single thread, without ever really pausing it?

Meet the Event Loop

Unlike other languages, JavaScript doesn’t just keep on executing code in a linear fashion from top to bottom. It is an asynchronous event driven language with tons of magic in the form of event loop. Event loop splits your code in synchronous and certain events - like timers and HTTP requests. Precisely speaking, there are two queues - task queue and microtask queue. Whenever you run JS, and there’s an asynchronous thing (like a mouseclick event, or a promise) JavaScript throws it in the task queue (or microtask queue) and keeps executing. When it completes a “single tick” - it checks if task queues and microtask queue has some work for it. If yes, then it’ll execute the callback/perform an action.

I would really recommend anyone interested in deep working of event loop to watch this video:

Conclusion

You came here for a simple sleep instruction in JavaScript, ended up learning about one of the core things in JavaScript - event loop! Amazing, isn’t it?

Originally published by Mehul Mohan at https://www.freecodecamp.org

#javascript #web-development

Rahul Jangid

1622207074

What is JavaScript - Stackfindover - Blog

Who invented JavaScript, how it works, as we have given information about Programming language in our previous article ( What is PHP ), but today we will talk about what is JavaScript, why JavaScript is used The Answers to all such questions and much other information about JavaScript, you are going to get here today. Hope this information will work for you.

Who invented JavaScript?

JavaScript language was invented by Brendan Eich in 1995. JavaScript is inspired by Java Programming Language. The first name of JavaScript was Mocha which was named by Marc Andreessen, Marc Andreessen is the founder of Netscape and in the same year Mocha was renamed LiveScript, and later in December 1995, it was renamed JavaScript which is still in trend.

What is JavaScript?

JavaScript is a client-side scripting language used with HTML (Hypertext Markup Language). JavaScript is an Interpreted / Oriented language called JS in programming language JavaScript code can be run on any normal web browser. To run the code of JavaScript, we have to enable JavaScript of Web Browser. But some web browsers already have JavaScript enabled.

Today almost all websites are using it as web technology, mind is that there is maximum scope in JavaScript in the coming time, so if you want to become a programmer, then you can be very beneficial to learn JavaScript.

JavaScript Hello World Program

In JavaScript, ‘document.write‘ is used to represent a string on a browser.

<script type="text/javascript">
	document.write("Hello World!");
</script>

How to comment JavaScript code?

  • For single line comment in JavaScript we have to use // (double slashes)
  • For multiple line comments we have to use / * – – * /
<script type="text/javascript">

//single line comment

/* document.write("Hello"); */

</script>

Advantages and Disadvantages of JavaScript

#javascript #javascript code #javascript hello world #what is javascript #who invented javascript