-2

I have an array of url:

var myurls = ["url1", "url2", "url3"];

And I want to fetch all urls one by one.

I know how to do it manually, but not for an array

fetchUrl1(myurls[0])
  .then(function(){
    return test_func(myurls[1]);
  })
  .then(function(){
    return test_func(myurls[2]);
  })
  .then(function() {
     console.log('done');
   });

How I can do that dynamically ?

2 Answers2

-1

Looks like there are some duplicate candidates in the comments, but nonetheless here is a concise answer that provides several methods depending on the specific requirements:

You can use asyncjs' eachSeries (if you want to use node-style callbacks) or bluebird's Promise.each if using promises to fetch the URLs in series. If you don't need the fetching to happen in series, but they can all be fetched in parallel, asyncjs' each and ES6's Promise.all will allow you to do that.

Both of these methods take functions as inputs, so you would take the original array of URLs and map them to the desired input functions and your final output would be an array of results (I'm assuming the responses from the URL fetching).

EDIT: including example code with Promise.each

var myurls = ["url1", "url2", "url3"];
var myPromisifiedFetchRequests = myurls.map(url => fetch(url));

Promise.each(myPromisifiedFetchRequests).then(myFetchedResults => console.log(myFetchedResults));
Lance Whatley
  • 2,395
  • 1
  • 13
  • 16
  • Thanks for your answer this is very specific because I want to use fetch – user8026049 May 23 '17 at 14:36
  • I'll try with Promise.each and update you, do you have an example of Pormise.each ? – user8026049 May 23 '17 at 14:37
  • I'm on react native – user8026049 May 23 '17 at 14:38
  • I updated my answer to provide example code as to how to use `Promise.each`. Let me know if you have any additional questions. – Lance Whatley May 23 '17 at 14:41
  • Thank you with react native I have a type error : Promise.each is not a function – user8026049 May 23 '17 at 14:45
  • Bluebird is a Library ok ! – user8026049 May 23 '17 at 14:49
  • Yep sorry, i included a link to `Promise.each` documentation in the original answer :) – Lance Whatley May 23 '17 at 14:53
  • now with bluebird I have this error "expecting a function but got [object Undefined]" – user8026049 May 23 '17 at 15:06
  • When you `map` your array to become an array of promises, can you confirm the function you're using exists on page? Can you provide the line of code where you are `map`ing your array to become an array of promises? – Lance Whatley May 23 '17 at 15:13
  • let myPromisifiedFetchRequests = fetcher.shouldBeFetched.map(url => fetch(url)); This is this line (the same as you) – user8026049 May 23 '17 at 15:44
  • What this tells me is the function `fetch` is not defined on the page. Can you confirm, and make sure to use the correct function required to `fetch` the response from the URL? The main concept is that your array of URLs needs to be transformed into an Array of promises to be resolved. As long as that's happening, `Promise.each` should work as explained. – Lance Whatley May 23 '17 at 16:25
  • Without using bluebird you can also just do Promise.all() – Matt Aft May 23 '17 at 22:45
  • Promise.all execute all of my task at the same time @MattAft ? – user8026049 May 24 '17 at 07:27
  • @LanceWhatley I have try let myPromisifiedFetchRequests = fetcher.shouldBeFetched.map(url => { console.log(url); return fetch(url); }); Promise.each(myPromisifiedFetchRequests).then(myFetchedResults => { console.log('test'); console.log(myFetchedResults); }); This is my code, now, he don't print 'test' but it print all of my url and after that he print "Unhandled rejection TypeError: expecting a function but got [object Undefined]" – user8026049 May 24 '17 at 07:29
  • @user8026049 Yea, it does them in parallel. if you want the responses from the api requests then the promise returns an array of the responses in the order you listed them in the promise.all. It will resolve only when every action is successfully completed otherwise it will reject. – Matt Aft May 24 '17 at 16:17
  • Oh ok I understand I don't want all task in parrallel, but just one by one – user8026049 May 27 '17 at 08:10
-1

You could use something like this. It builds a chain of promises that will resolve with an array of all results in the order of the original array. Here's a JSFiddle if you want to play with it: https://jsfiddle.net/53r4oxyh/

//dummy http.get
function HttpGet(url) {
  return new Promise((resolve, reject) => {
    console.log(`fetching ${url}`);
    setTimeout(function(){
        resolve(`done: ${url}`);
    }, Math.floor(Math.random()*500));
  });
}

function buildPromiseChain(items, func) {
  var promise = new Promise((resolve, reject) => {
    resolve([]);
  });
  items.forEach((item) => {
    promise = promise.then((result) => {
      return func(item).then((itemResult) => {
        result.push(itemResult);
        return result;
      });
    });
  });
  return promise;
}

buildPromiseChain(myurls, HttpGet).then((results) => console.log('done', results));
Dinu Sorin
  • 215
  • 2
  • 6