Promises with http.get node.js

I do exercises in schools,

This problem is the same as the previous problem (HTTP COLLECT) in which you need to use http.get (). However, this time you will be with three URLs as the first three command line arguments.

You must collect the full content provided to you by each of the URLs and print it to the console (stdout). You do not need to print the length, only the data as a string; one line per URL. The catch is that you should print them in the same order as the URLs. provided to you as command line arguments.

In other words, I have to register 3 http.get requests and print the data received from it in order.

I am trying to do this with promises = another receive request will not be called until the first one ends.

My code is as follows

var http=require("http");
var collect=[];
var dat=[];
for( var i = 2 ; i < process.argv.length;i++){
    collect.push(process.argv[i]);
}

function chainIt(array,callback){
    return array.reduce(function(promise,item){
        return promise.then(function(){
            return callback(item)
        })
    },Promise.resolve())
}



function getIt(item){
    return http.get(item,function(response){
        response.on("data",function(data){
                dat.push(data);
        })

    })
}


chainIt(collett,function(item){
    return getIt(item)
    })
}).then(function(){
    collect.forEach(function(x){
            console.log(x);
    })

})

But I am not actually printing data = I am not doing the exercise.

I don't see any error here, but I start with promises and node. Where is the mistake?

+4
source share
4 answers

http https, native Promise s. , , ​​ request; , unit test, . , , , .

FYI: Node.js 4 , Node 0.x.x.

'use strict';

const http = require('http');
const url = require('url');

module.exports = {
    get(url) {
        return this._makeRequest('GET', url);
    },

    _makeRequest(method, urlString, options) {

        // create a new Promise
        return new Promise((resolve, reject) => {

            /* Node URL library allows us to create a
             * URL object from our request string, so we can build
             * our request for http.get */
            const parsedUrl = url.parse(urlString);

            const requestOptions = this._createOptions(method, parsedUrl);
            const request = http.get(requestOptions, res => this._onResponse(res, resolve, reject));

            /* if there an error, then reject the Promise
             * (can be handled with Promise.prototype.catch) */
            request.on('error', reject);

            request.end();
        });
    },

    // the options that are required by http.get
    _createOptions(method, url) {
        return  requestOptions = {
            hostname: url.hostname,
            path: url.path,
            port: url.port,
            method
        };
    },

    /* once http.get returns a response, build it and 
     * resolve or reject the Promise */
    _onResponse(response, resolve, reject) {
        const hasResponseFailed = response.status >= 400;
        var responseBody = '';

        if (hasResponseFailed) {
            reject(`Request to ${response.url} failed with HTTP ${response.status}`);
        }

        /* the response stream (an instance of Stream) current data. See:
         * https://nodejs.org/api/stream.html#stream_event_data */
        response.on('data', chunk => responseBody += chunk.toString());

        // once all the data has been read, resolve the Promise 
        response.on('end', () => resolve(responseBody));
    }
};

EDIT: , Promise s. :

'use strict';

const httpService = require('./httpService'); // the above wrapper

// get one URL
httpService.get('https://ron-swanson-quotes.herokuapp.com/v2/quotes').then(function gotData(data) {
    console.log(data);
});

// get multiple URLs
const urls = [
    'https://ron-swanson-quotes.herokuapp.com/v2/quotes',
    'http://api.icndb.com/jokes/random'
];

/* map the URLs to Promises. This will actually start the
 * requests, but Promise.prototype.then is always called,
 * even if the operation has resolved */
const promises = urls.map(url => httpService.get(url));

Promise.all(promises).then(function gotData(responses) {
    /* responses is an array containing the result of each
     * Promise. This is ordered by the order of the URLs in the
     * urls array */

    const swansonQuote = responses[0];
    const chuckNorrisQuote = responses[1];

    console.log(swansonQuote);
    console.log(chuckNorrisQuote);
});
+4

- "Q".

, URL

var Q = require('q);
function getIt(item){
 return http.get(item,function(response){

       return Q.resolve(response); // Return response
         OR
       return Q.resolve(error);    // Return error

     })
  })
}



var urls = ['url1','url2','url3']; // list of urls

Q.spread(urls.map(getIt))
 .then(function(res1,res2,res3){ 

    // res1 is response for url1 and on
    //Once all calls are finished you will get results here
 });
0

, promises. , promises :

var http = require('http');
var urls = process.argv.slice(2);

// counts the number of requests done
var done = 0;
// stores the requests result
var result = [];

// this will be called by each http.get and they will provide their index
function callback(index, data) {
  result[index] = data;
  done++;
  // all requests are done, log everything
  if (done == urls.length) {
    result.forEach(console.log);
  }
}

function processUrl(url, index) {
  var finalData = '';
  http.get(url, function(response) {
    response.setEncoding('utf8');
    response.on('data', function(data) {
      finalData += data;
    });
    response.on('error', console.error);
    response.on('end', function() {
      // console.log(finalData);
      callback(index, finalData);
    })
  });
}

urls.forEach(processUrl);

Do not worry, you will have enough promises to play in the workshop promise-it-wont-hurt.

0
source

Here is my solution after going through this topic:

var http = require('http');
var bl   = require('bl') 

promises = [
    promiseLoad(process.argv[2]),
    promiseLoad(process.argv[3]),
    promiseLoad(process.argv[4])
];

Promise.all(promises).then(function(res) {

  for(i=0; i<promises.length; i++) {
    console.log(res[i]);
  }
});

function promiseLoad(url) {
  var body = '';
  return new Promise(function(resolve, reject) {
    http.get(url, function (response) { 
    response.setEncoding('utf8'); 
       response.pipe(bl(function (err, data) {  
         resolve(data.toString())
       }))  
     })
  });
}

Here's the official solution if you want to compare notes:

 var http = require('http')  
 var bl = require('bl')  
 var results = []  
 var count = 0  

 function printResults () {  
   for (var i = 0; i < 3; i++) {  
     console.log(results[i])  
   }  
 }  

 function httpGet (index) {  
   http.get(process.argv[2 + index], function (response) {  
     response.pipe(bl(function (err, data) {  
       if (err) {  
         return console.error(err)  
       }  

       results[index] = data.toString()  
       count++  

       if (count === 3) {  
         printResults()  
       }  
     }))  
   })  
 }  

 for (var i = 0; i < 3; i++) {  
   httpGet(i)  
 }
0
source

Source: https://habr.com/ru/post/1627180/


All Articles