Creating a Command Line Interface (CLI) application in JavaScript for the browser: A guide to simulating blocking I/O

Developing a CLI application becomes quite simple with a blocking I/O API like PrintLn / ReadLn, making the process smooth and efficient.

However, the challenge arises when trying to create a terminal application that runs on a browser using JS. In this scenario, input events are asynchronous, which means you cannot block the function midway through while waiting for input without disrupting the application's state.

I am currently grappling with designing the event loop and structuring the architecture of the JavaScript code. This is especially tricky as there will be multiple levels of commands within the app, and I want to avoid falling into the trap of "callback hell". Could someone please guide me to a resource or provide tips on how to architect this design? Thank you.

Answer №1

Implementing Promises in Your Code

  1. Submit user input
  2. Disable new input submission temporarily
  3. Invoke a Promise function
  4. Show the result after the Promise has been fulfilled
  5. Enable terminal for new inputs

// Triggering the operation upon submitting
function submit(userInput) => {

  // Temporarily disable terminal
  blockTerminal();

  // Processing the user's command
  // Invoking an async Promise
  // Result displayed once operation is complete
  doSomething(userInput).then(result => {

    // Displaying outcome in the terminal
    output(result);

    // Re-enable terminal for new inputs
    releaseTerminal();
  })
}

// The asynchronous code being executed
// Returns a Promise object
function doSomething(userInput) => {
  return new Promise(resolve => {

    // Simulating a delay of 2500ms
    setTimeout(() => {
      resolve('result')
    }, 2500)
  })
}

In a live environment, replace setTimeout() with an Ajax call and use resolve(response) upon success.


Alternatively, consider exploring RxJS.

RxJS introduces Observable streams in JavaScript, which are highly effective for handling asynchronous operations. Though more complex than Promises, they offer powerful functionalities.

Answer №2

To accomplish this, you can utilize the async/await functionality.

function fetchInput(){
  return new Promise(response =>{
    document.querySelector('#submit').addEventListener('click', () => response(document.querySelector('#inputValue').value, {once:true}))
  })
}

async function execute(){
  for(let i=0;;++i){
    let input = await fetchInput()
    console.log(`${i}:${input}`)
  }
}

execute()
<input type="text" id="inputValue">
<input type="button" value="Submit" id="submit">

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging the power of ES6 capabilities within the Express.js framework of Node

Recently, I've been experimenting with utilizing ES6 features in Express. Interestingly, I discovered that Nodejs now has built-in support for es6, eliminating the need for babel to transpile my code. Here's a snippet from my app.js file: &apos ...

Guide on redirecting to a specific Vue-app page using Flask

I am currently working on an application that includes a page that ends with '@' and provides meta information for the page without '@'. For example, if the page '/user/aabb' contains information about the user 'aabb&apos ...

Encountered an issue with instafeed.js due to CORS policy restrictions

Trying to implement an API that provides JSON data for use in a function. Required Imports: Importing Jquery, instafeed.min.js, and the API (instant-tokens.com). <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js& ...

Exploring the Differences Between NPM Jquery on the Client Side and Server

I'm still getting the hang of node and npm, so this question is more theoretical in nature. Recently, I decided to incorporate jQuery into my website by running npm install jquery, which placed a node_modules directory in my webpage's root along ...

Operators within an observable that perform actions after a specific duration has elapsed

Is there a way in an rxjs observable chain to perform a task with access to the current value of the observable after a specific time interval has elapsed? I'm essentially looking for a functionality akin to the tap operator, but one that triggers onl ...

How can I obtain an array using onClick action?

Can anyone help me figure out why my array onClick results are always undefined? Please let me know if the explanation is unclear and I will make necessary adjustments. Thank you! Here is the code snippet: const chartType = ["Line", "Bar", "Pie", " ...

Buefy table in Vue with various row statuses

One interesting feature of Buefy tables is the ability to highlight rows with a specific color based on a variable in the row. :row-class="(row, index) => row.variable === x && 'is-info'"> In order to style the specific row class: <styl ...

Can you provide me the steps to delete the title attribute from images in Wordpress?

My client has expressed dissatisfaction with the tooltip that appears when hovering over images in certain browsers, particularly Safari. This tooltip displays the title attribute within the img tag, which is a requirement enforced by Wordpress. Even if w ...

Issues with Ajax calls not functioning properly within CakePHP

I'm attempting to make an AJAX request in CakePHP. The submit button is marked as #enviar and the action as pages/contato. This is the code for my AJAX request: $(document).ready(function() { $('#enviar').click(function(){ $. ...

What is the process for removing a Discord user using Node.js?

I've been working on creating a discord bot using node.js, but I'm facing an issue where nothing happens when I try to use a command. The console doesn't log anything except for the bot coming online. const Prefix = '$'; bot.on(&a ...

JavaScript: locating web addresses in a text

Need help searching for website URLs (e.g. www.domain.com) within a document and converting them into clickable links? Here's how you can do it: HTML: Hey there, take a look at this link www.wikipedia.org and www.amazon.com! JavaScript: (function( ...

React.js pagination - removing empty values from an array

I'm currently working on implementing pagination logic that automatically updates the page numbers when the last index is clicked. For example: 1 2 3 4 5 If a user clicks on the number 5, it should display: 2 3 4 5 6 and so forth... I have succe ...

Retrieve the latest inserted ID in a Node.js application and use it as a parameter in a subsequent query

I am currently working with an SQL database that consists of two tables, namely club and players. These tables are connected through a one-to-many relationship. Although the query in my node.js code is functioning properly, I am facing an issue retrieving ...

How to Calculate the Time Interval Between Two CORS Requests Using jQuery AJAX

When using jQuery's $.ajax to make a CORS request to a web service, there is typically a pre-flight request followed by the actual POST request. I have observed that when there is a time gap between making two web service calls, both a pre-flight and ...

Sorting Tables through the Power of Drag and Drop

While utilizing both the Jquery Tablesorter plugin and the Drag and Drop plugin together, everything seems to be functioning correctly. However, when attempting to use the serialize function of the tableDnD, an error message stating "empty string getElemen ...

SVGs do not display on iPhones

Having some issues with my code - specifically, I have an SVG animation that seems to work on all devices except iPhones. I've been struggling to find a solution. Here is the code snippet for the SVG: <div class="contenuto-svg"> <svg vi ...

Potential issue with Jhipster: loading of data could be experiencing delays

I've encountered an issue with getting my chart to display properly. I am working on creating a chart using ng2-charts, where I retrieve data from a service and then display it on the chart. The problem arises when the data is not correctly displayed ...

Problem integrating multer with Express JS and Node JS

Click here to access the server.js file on GitHub Following a tutorial, I have implemented code accordingly. However, when working with an updated version of Express JS, errors are being thrown on the side of Express JS. Error C:\nodefiles&bso ...

Exploring Angular 8 HTTP Observables within the ngOnInit Lifecycle Hook

Currently, I am still a beginner in Angular and learning Angular 8. I am in the process of creating a simple API communication service to retrieve the necessary data for display. Within my main component, there is a sub-component that also needs to fetch ...

Activate on-demand static regeneration with Next.js

I am thoroughly impressed by the functionality of Incremental Static Regeneration in Next.js. However, I am currently seeking a method to manually trigger static page regeneration as needed. It would be ideal to have a command that can be executed via an ...