This is the 27th day of my participation in Gwen Challenge

Promise resolves concurrent requests – interview questions

var urls = [
  'http://jsonplaceholder.typicode.com/posts/1'.'http://jsonplaceholder.typicode.com/posts/2'.'http://jsonplaceholder.typicode.com/posts/3'.'http://jsonplaceholder.typicode.com/posts/4'.'http://jsonplaceholder.typicode.com/posts/5'.'http://jsonplaceholder.typicode.com/posts/6'.'http://jsonplaceholder.typicode.com/posts/7'.'http://jsonplaceholder.typicode.com/posts/8'.'http://jsonplaceholder.typicode.com/posts/9'.'http://jsonplaceholder.typicode.com/posts/10'
]

function loadDate (url) {
  return new Promise((resolve, reject) = > {
    const xhr = new XMLHttpRequest()
    xhr.onload = function () {
      resolve(xhr.responseText)
    }
    xhr.open('GET', url)
    xhr.send()
  })
}
Copy the code

Ten interface addresses are stored in the urls array. We also define a loadDate function that takes a URL argument and returns a Promise object that returns resolve on success and reject on failure.

Requirements: No more than 3 links can be downloaded at any one time. Try writing code that implements the requirement to get data from all interfaces as quickly as possible.


Their thinking

We can do this by making concurrent requests for data from three urls. When one of the urls gets the data, we immediately make a request for data from a new URL. We keep the number of concurrent requests at three until all the urls that need to load data have completed the request and get the data.

The idea behind promises is to ask for three urls simultaneously, get three promises, and then make an array called Promises. Keep calling promise. race to return the fastest Promise to change state. Then delete promises from the promises array and add a new Promise until all urls are fetched. Promise. All: Promises in promises that do not change state

Refer to the answer

var urls = [
  'http://jsonplaceholder.typicode.com/posts/1'.'http://jsonplaceholder.typicode.com/posts/2'.'http://jsonplaceholder.typicode.com/posts/3'.'http://jsonplaceholder.typicode.com/posts/4'.'http://jsonplaceholder.typicode.com/posts/5'.'http://jsonplaceholder.typicode.com/posts/6'.'http://jsonplaceholder.typicode.com/posts/7'.'http://jsonplaceholder.typicode.com/posts/8'.'http://jsonplaceholder.typicode.com/posts/9'.'http://jsonplaceholder.typicode.com/posts/10'
]

function loadDate (url) {
  return new Promise((resolve, reject) = > {
    const xhr = new XMLHttpRequest()
    xhr.onload = function () {
      resolve(xhr.responseText)
    }
    xhr.open('GET', url)
    xhr.send()
  })
}

function limitLoad(urls, handler, limit) {
    // Make a copy of the array
    const sequence = [].concat(urls)
    let promises = [];

    // Achieve the maximum number of concurrent requests
    promises = sequence.splice(0, limit).map((url, index) = > {
        // The index returned here is the footer of the task in the array Promises
        // Used to find completed task pins after promise.race
        return handler(url).then(() = > {
            return index
        }); 
    });

    // Use the array reduce method to execute as a queue
    return sequence.reduce((last, url, currentIndex) = > {
        return last.then(() = > {
            // Return the Promise with the fastest state change
            return Promise.race(promises)
        }).catch(err= > {
            // Catch is not only used to catch errors thrown by previous THEN methods
            // More importantly, to prevent the entire chain call from breaking
            console.error(err)
        }).then((res) = > {
            // Replace the fastest-changing Promise with a new Promise
            promises[res] = handler(sequence[currentIndex]).then(
                () = > { returnres }); })},Promise.resolve()).then(() = > {
        return Promise.all(promises)
    })
    
}
limitLoad(urls, loadDate, 3)

/* Since loadDate also returns a Promise, limitLoad(urls, loadDate, urls) can continue to be chained when all images are loaded 3). Then (() => {console.log(' all URL data requests were successful '); }).catch(err => { console.error(err); }) * /
Copy the code

This points to the problem

function Foo() {
  getName = function () {
    console.log(1);
  };
  return this;
}
Foo.getName = function () {
  console.log(2);
};
Foo.prototype.getName = function () {
  console.log(3);
};
var getName = function () {
  console.log(4);
};
function getName() {
  console.log(5);
}
Foo.getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
Copy the code

Refer to the answer

1, Foo getName ();

Call Foo’s static method, so print 2

2, Foo (). The getName ();

Foo() is a normal function call that returns this as window, followed by window.getName(), and the getName under window that calls getName in Foo() is reassigned, so print 1

3, getName ();

Foo().getName(), so getName=function(){console.log(1)}, so print 1, [if getName() on Foo().getName() print 4]

4, new Foo getName ();

Constructor private property getName(), so print 2

5, new Foo (). The getName ();

GetName () on the prototype, print 3

6、 new new Foo().getName()

First new Foo() gets an empty object {}

The second step adds an attribute getName to the empty object with a value of a function

New {}.getName()

Var bar = new (new Foo().getName)(); Console. log(bar) first new Foo’s getName method on the instance object, and then continues new with getName method on the prototype as constructor, so executes the prototype method and prints 3