skip to Main Content

Please, help me with this code. It runs very slow, about 2 minutes. I’m new to js and don’t know how to improve it. I need to take data from multiple ajax requests and compare it. I tried to use for loops, $.map, but it works the same. What i’m doing wrong?

var user, post, image, comment;

$.when(
  $.ajax({
    url: "https://jsonplaceholder.typicode.com/posts",
    success: function(postData) {
      post = postData;
    },
  }),
  $.ajax({
    url: "https://jsonplaceholder.typicode.com/comments",
    success: function(commentData) {
      comment = commentData;
    },
  }),
  $.ajax({
    url: "https://jsonplaceholder.typicode.com/users",
    success: function(userData) {
      user = userData;
    },
  }),
  $.ajax({
    url: "https://jsonplaceholder.typicode.com/photos",
    success: function(imageData) {
      image = imageData;
    },
  }),
).then(function() {
  $.each(post, function(index, postItem) {
    $.each(comment, function(index, commentItem) {
      $.each(user, function(index, userItem) {
        $.each(image, function(index, imageItem) {
          if (
            postItem.id == commentItem.postId &&
            postItem.id == imageItem.id &&
            postItem.userId == userItem.id
          ) {
            console.log(
              "post title: " +
                postItem.title + 
                " Post image: " +
                imageItem.url +
                " Author: " +
                userItem.name +
                " Comment: " +
                commentItem.body
            );
          }
        });
      });
    });
  });
});

2

Answers


  1. For the comments, users, and photos, transform the array of objects into a Map (or object), whose keys are the ids, and values are the values you want to extract from it later. Then loop over the posts, and from the ids in the post, look up the matching values on the Maps. If all 3 maps have a match, print the result.

    Note that there’s no need for a large dependency like jQuery just to make a network request and iterate over an array – built-in JS methods works just fine:

    Promise.all(
      ['posts', 'comments', 'users', 'photos'].map(
        path => fetch('https://jsonplaceholder.typicode.com/' + path).then(res => res.json())
      )
    ).then(([posts, comments, users, images]) => {
      const commentBodiesByPostId = new Map(
        comments.map(comment => [comment.postId, comment.body])
      );
      const imageUrlsById = new Map(
        images.map(image => [image.id, image.url])
      );
      const userNamesById = new Map(
        users.map(user => [user.id, user.name])
      );
      for (const post of posts) {
        const commentBody = commentBodiesByPostId.get(post.id);
        const imageUrl = imageUrlsById.get(post.id);
        const userName = userNamesById.get(post.userId);
        if (commentBody && imageUrl && userName) {
          console.log(`Post title: ${post.title}nPost image:${imageUrl}nAuthor:${userName}nComment:${commentBody}`);
        }
      }
    });
    Login or Signup to reply.
  2. Using my Mapper util, you can optimise it very fast. see the sample.

    You can find script here:
    https://gist.github.com/deepakshrma/4b6a0a31b4582d6418ec4f76b7439781

    var user, post, image, comment;
    const results = Promise.all(
      [
        fetch("https://jsonplaceholder.typicode.com/posts").then( x => x.json()),
        fetch("https://jsonplaceholder.typicode.com/comments").then( x => x.json()),
        fetch("https://jsonplaceholder.typicode.com/users").then( x => x.json()),
        fetch("https://jsonplaceholder.typicode.com/photos").then( x => x.json())
      ]
    ).then(function([posts, comments, users, images]) {
      const postMapper = new Mapper(posts, "id")
      const commentMapper = new Mapper(comments, "postId")
      const userMapper = new Mapper(users, "id")
      const imageMapper = new Mapper(images, "id")
      console.log(posts, comments, users, images)
      posts.forEach(post => {
        const postM = postMapper.find(post.id)
        const userM = userMapper.find(post.userId)
        const imagM = imageMapper.find(post.id)
        console.log(
          postM, 
          userM,
          imagM
        )
      })
    });
    class Mapper {
      constructor(array, key) {
        this.map = array.reduce((map, item) => {
          const val = item[key];
          if (!map[val]) {
            map[val] = [];
          }
          map[val].push(item);
          return map;
        }, {});
      }
    
      find(key) {
        return this.map[key] && this.map[key][Mapper.FIRST_INDEX]; //return blank array
      }
    
      findAll(key, returnUndefined) {
        //return blank array
        return this.map[key] ? this.map[key] : returnUndefined ? undefined : [];
      }
    }
    
    Mapper.FIRST_INDEX = 0;
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search