This is the 23rd day of my participation in the August More Text Challenge

This series also does not have any tricks, is to complete the usual interview some handwriting functions, test these simple implementation of the advantage is that you can see the basic coding level, and take a short time, a more comprehensive view of your code strength. Generally, there are not many boundary conditions, so that the interview time is not enough, the investigation is not comprehensive.

If you don’t know or are not clear about the API, just ask the interviewer directly, how to use the API under Google anyone can immediately understand the knowledge also can’t see the level. The key is in the implementation process, and your coding status, habits, clarity of thought and so on.

Note that it is a simple implementation, not a complete implementation. It is important to have a clear concept and clear implementation idea. It is suggested to explain the concept clearly first => write use cases => write pseudocode => implement specific functions, and then optimize step by step.

32. Concurrency control

What’s the problem

When we build complex websites, we often need to load a large number of resources of different sizes

For example, a page starts with dozens of images (or more) that are almost concurrent requests, whereas Chrome supports a limited number of concurrent requests, and other requests are pushed into a queue until the previous round is complete.

This results in – too long loading time – poor first screen experience

How can we optimize – lazy loading (the core is only loading resources in the visible area) – to limit the number of concurrent loads

Instead of focusing on Lazyloading, today’s focus is on limiting the number of files that can be concurrently loaded.

Let’s start with some basic concepts

Concurrency and parallelism

So let’s talk a little bit about what is concurrency, what is parallelism

I took zhihu high praise of the answer, very image

  • You’re in the middle of a meal when the phone comes and you don’t answer it until after you’ve finished, which means you don’t support concurrency or parallelism.
  • You’re in the middle of a meal when the phone call comes, you stop to answer the phone, and then continue eating, which means you support concurrency.
  • You’re in the middle of a meal when the phone call comes and you’re eating while you’re talking, which means you support parallelism.

So let’s understand

  • The key to concurrency is that you have the ability to handle multiple tasks, not necessarily all at once.

  • The key to parallelism is your ability to handle multiple tasks at once.

So I think the key thing about them is whether they are simultaneous or not, which is the simultaneity where the ear is listening and the mouth is eating.

Ears and mouth can be regarded as the dual core of the CPU, which can be simultaneously computed.

Let’s take a look at the foreign drawings of concurrency and parallelism

Why do browsers request concurrency limits?

The maximum number of concurrent requests for the same domain name is set by the browser. The maximum number of concurrent requests is usually 4 to 8.

  1. For operating system port resources, a TCP (HTTP and TCP) connection takes up one port so that the number of ports does not quickly run out

  2. Excessive concurrency leads to frequent switching, resulting in performance problems

  3. To prevent a large number of concurrent requests from the same client from exceeding the concurrency threshold of the server, the server usually sets a concurrency threshold for the same client source to prevent malicious attacks

  4. Client conscience mechanism (when two applications seize resources, the strong party has unlimited access to resources and the weak party blocks forever)

Now that the basic concepts are understood, here’s the code

Code implementation

First, prepare some resources with id, name and timeConsuming of each resource.

const resources = [{
    id: 1.name: 'img1'.timeConsuming: 3000
}, {
    id: 1.name: 'img2'.timeConsuming: 2500}, {id: 1.name: 'img3'.timeConsuming: 1000}, {id: 1.name: 'img4'.timeConsuming: 1000}, {id: 1.name: 'img5'.timeConsuming: 2000}, {id: 1.name: 'img6'.timeConsuming: 1500
}];
Copy the code

We need a way to load these resources in, and we use Promise to simulate asynchronous loading

function loadSrc(resource) {
    return new Promise((resolve, reject) = > {
        console.log(resource.name + 'is loading ... ');
        // Simulate an asynchronous event to download a file resource
        setTimeout(() = > {
            console.log(resource.name + 'is loaded successfully ! ');
            resolve();
        }, resource.timeConsuming)
    })
};
Copy the code

So, how do you limit concurrency, given the Promise that was implemented yesterday

This method is designed with three inputs

  • The resource list
  • Processing method (download, burial point, notification, etc.)
  • Maximum number of concurrent requests

! Note that when some tasks are completed in the concurrent process, the following tasks fill in bits in time to ensure the maximum number of concurrent tasks.

So you can’t do n, n loops and Promise. All.

const limitLoader = (srcs, handler, limit) = > {
    // Copy the parameter so that it does not affect variables passing in reference types
    let resources = JSON.parse(JSON.stringify(srcs))
    // This array is used to store asynchronous tasks that can be executed concurrently
    let promises = new Array(limit)

    // First cut off the previous limit number of resources into Promises
    // And the original array is changed to leave the unexecuted tasks
    // Promises: [P1, P2, p3] [R4, r5, r6]
    promises = resources.splice(0, limit).map((item, index) = > {
        // Perform a handler for each promise and return index
        // Why return index, because if P1 is executed, promises current index will be left empty for future tasks
        return handler(item).then(() = > {
            return index
        })
    })
    // Get the first terminating Promise, noting that race only returns the first terminating result, but the rest of the promises are still executed
    let endProRes = Promise.race(promises);
    // The next step is to iterate over the remaining resources, one by one
    for (let i = 0; i < resources.length; i++) {
        endProRes = endProRes.then((res) = > {
            // The res is the index returned above. The next offset is to promises
            promises[res] = handler(resources[i]).then(() = > {
                // 结束还是返回 index
                return res
            })
            // Then the next race, to the next
            return Promise.race(promises)
        })
    }
    / / this cycle can actually as endProRes. Then (). Then (). Then ()...
}

limitLoader(resources, loadSrc, 3)
Copy the code

The output

img1is loading ...
img2is loading ...
img3is loading ...
img3is loaded successfully !   // The third one is executed first
img4is loading ...             // The fourth index immediately completes the third index
img4is loaded successfully !
img5is loading ...
img2is loaded successfully !
img6is loading ...
img1is loaded successfully !
img5is loaded successfully !
img6is loaded successfully !
Copy the code

This enables you to control the number of concurrent loads of resources

Please leave a comment and I will answer it 99% of the time (unless there are too many people and the question is different).

In addition, we recommend another series of articles, very simple, on the front of the advanced students are very effective, wall crack recommended!! Core concepts and algorithms disassembly series remember to like ha

If you want to brush the questions with me, you can add me on wechat. Click here to make a friend Or search my wechat account, infinity_9368. You can chat with me and add my secret code “Tianwang Gaidihu”. Verify the message please send me Presious tower shock the rever Monster, I see it through, after adding I will do my best to help you, but pay attention to the way of asking questions, it is suggested to read this article: the wisdom of asking questions

reference

  • www.zhihu.com/question/33…
  • MDN
  • elevation