Skip to content

Instantly share code, notes, and snippets.

View semlinker's full-sized avatar
👊
Fighting

阿宝哥 semlinker

👊
Fighting
View GitHub Profile
@semlinker
semlinker / big-file-without-gzip.js
Created July 31, 2022 11:49
HTTP Transfer Large Files
const fs = require("fs");
const http = require("http");
const util = require("util");
const readFile = util.promisify(fs.readFile);
const server = http.createServer(async (req, res) => {
res.writeHead(200, {
"Content-Type": "text/plain;charset=utf-8",
});
const buffer = await readFile(__dirname + "/big-file.txt");
@semlinker
semlinker / util.d.ts
Created July 31, 2022 02:33
Use TypeScript Conditional Types Like a Pro
type FunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;
type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;
@semlinker
semlinker / index.html
Last active November 20, 2024 17:31
Implement Concurrent Download of Large Files in JavaScript
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Concurrent Download Demo</title>
<script src="multi-thread-download.js"></script>
</head>
<body>
@semlinker
semlinker / saveAs.js
Created July 25, 2022 10:46
Save File
function saveAs({ name, buffers, mime = "application/octet-stream" }) {
const blob = new Blob([buffers], { type: mime });
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.download = name || Math.random();
a.href = blobUrl;
a.click();
URL.revokeObjectURL(blob);
}
@semlinker
semlinker / download-chunk.js
Created July 25, 2022 10:43
Download Chunk
async function download({ url, chunkSize, poolLimit = 1 }) {
const contentLength = await getContentLength(url);
const chunks = typeof chunkSize === "number" ? Math.ceil(contentLength / chunkSize) : 1;
const results = await asyncPool(
poolLimit,
[...new Array(chunks).keys()],
(i) => {
let start = i * chunkSize;
let end = i + 1 == chunks ? contentLength - 1 : (i + 1) * chunkSize - 1;
return getBinaryContent(url, start, end, i);
@semlinker
semlinker / get-content-length.js
Created July 25, 2022 10:34
Get content length
function getContentLength(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("HEAD", url);
xhr.send();
xhr.onload = function () {
resolve(
~~xhr.getResponseHeader("Content-Length")
);
};
@semlinker
semlinker / concatenate.js
Created July 25, 2022 10:32
Concatenate Function
function concatenate(arrays) {
if (!arrays.length) return null;
let totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
let result = new Uint8Array(totalLength);
let length = 0;
for (let array of arrays) {
result.set(array, length);
length += array.length;
}
return result;
@semlinker
semlinker / get-binary-content.js
Created July 25, 2022 10:27
Get Binary Content
function getBinaryContent(url, start, end, i) {
return new Promise((resolve, reject) => {
try {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.setRequestHeader("range", `bytes=${start}-${end}`); // Set range request information
xhr.responseType = "arraybuffer"; // Set the returned type to arraybuffer
xhr.onload = function () {
resolve({
index: i, // file block index
@semlinker
semlinker / promise.race.js
Created July 25, 2022 03:58
Promise.race
Promise.race = function (iterators) {
return new Promise((resolve, reject) => {
for (const iter of iterators) {
Promise.resolve(iter)
.then((res) => {
resolve(res);
})
.catch((e) => {
reject(e);
});
@semlinker
semlinker / promise.all.js
Created July 25, 2022 03:57
Promise.all
Promise.all = function (iterators) {
return new Promise((resolve, reject) => {
if (!iterators || iterators.length === 0) {
resolve([]);
} else {
// used to determine whether all tasks are completed
let count = 0;
let result = []; // result array
for (let i = 0; i < iterators.length; i++) {
// Considering that iterators[i] may be ordinary object,