https://segmentfault.com/a/1190000039275224
默认返回一个new Promise,其他的,在这个返回里面去做
- Promise.all:如果都成功则返回成功数据(resolve),如果有一个失败了,则立即reject返回,即有失败的下面就不走了
- Promise.allSettled:会返回所有数据,成功的返回状态和值,不成功的返回状态和原因,即便中间不成功也不会打断执行,会将所有接口运行完才做数据返回
- Promise.any:任意一个promise成功就返回这个值
- Promise.race:任意一个promise成功或者失败后,返回这个值,成功就返回成功值,失败返回失败值
- Promise.resolve(value):返回一个状态由给定 value 决定的 Promise 对象
- Promise.reject(reason):返回一个状态为已拒绝的 Promise 对象,并将给定的失败信息传递给对应的处理函数
有两种方式能拿到错误值,一种是.catch;另一个是在then的第二个参数里能直接拿到reject的原因,并且如果我在.then里拿到了错误原因,那.catch就拿不到错误原因了,走不到这步了
const pr = new Promise((resolve, reject) => {
reject(111)
})
// 在.then里处理的reject的原因了,所以不会走到.catch的方法里
// 所以结果为:then 111
pr.then((value) => {}, (reason) => {console.log('then', reason)}).catch(error => console.log('catch', error))
// 这里没有在.then里去做reject的处理,所以可以走到.catch中间
// catch 111
pr.then((value) => {}).catch(error => console.log('catch', error))
// 后续的then不会随着前面的catch有变化,会一直继续向下做请求,展示then的值
// then 111, 0000
pr.then((value) => {}, (reason) => {console.log('then', reason)})
.catch(error => console.log('catch', error))
.then(() => console.log('0000'))
// 即使使用了finally也会继续走到后面的then里,只要后面有
// 结果:22、 222222、2345
pr.then((value) => {})
.catch((ee) => console.log('22'))
.finally(() => console.log('222222'))
.catch(ee => console.log(ee))
.then(value => console.log(2345))
// finally如果抛出去一个error,那么后续也会被catch接住
// 22、Error: 123,2345
pr.then((value) => {})
.catch((ee) => console.log('22'))
.finally(() => {throw Error('123')})
.catch(ee => console.log(ee))
.then(value => console.log(2345))
Promise.all
// arr 传过来的接口请求
const Promise_all = (arr) => {
if (!Array.isArray(arr)) {
throw new Error('参数错误')
}
// 重点需要返回一个promise
return new Promise((resolve, reject) => {
// 一共完成了多少个
let num = 0;
// 返回的结果数组
const result = [];
for(let i = 0; i < arr.length; i++) {
// 单条去调用promise,成功后的结果回显到result数组
// then有两个函数参数,一个是成功,一个是失败
Promise.resolve(arr[i]).then(res => {
num++;
result[i] = res;
// 如果result数组的长度与arr相同了,则说明处理完了
if (num === arr.length) {
return resolve(result);
}
}, reason => {
// 失败了直接终止
return reject(reason);
})
}
})
}
Promise.race
// promise_race
const promise_race = (arr) => {
if (!Array.isArray(arr)) {
throw new Error('失败参数')
}
return new Promise((resolve, reject) => {
for(let i = 0; i < arr.length; i++) {
Promise.resolve(arr[i]).then(res => {
resolve(res)
}, reason => {
reject(reason)
})
}
})
}
Promise
class MyPromise {
// 构造函数
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// promise内置resolve
const resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
this.onResolvedCallbacks.forEach((callback) => callback(value));
}
};
// promise内置reject
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => callback(reason));
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
// then方法
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason };
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === "fulfilled") {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === "rejected") {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
// catch方法
catch(onRejected) {
return this.then(null, onRejected);
}
// finally方法
finally(onFinally) {
return this.then(
(value) => MyPromise.resolve(onFinally()).then(() => value),
(reason) =>
MyPromise.resolve(onFinally()).then(() => {
throw reason;
})
);
}
// Promise.resolve方法
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
// 链循环了
reject(new TypeError("Chaining cycle detected for promise"));
}
let called = false;
if (x instanceof MyPromise) {
x.then((value) => {
// resolve方法
this.resolvePromise(promise2, value, resolve, reject);
},
// reject方法
(reason) => {
if (!called) {
called = true;
reject(reason);
}
});
}
else if (x !== null && (typeof x === "object" || typeof x === "function")) {
try{
const then = x.then;
if (typeof then === "function") {
then.call(x,
(y) => {
// resolve
if (!called) {
called = true;
this.resolvePromise(promise2, y, resolve, reject);
}
},
// reject
(reason) => {
if (!called) {
called = true;
reject(reason);
}
}
);
} else {
resolve(x);
}
} catch {
resolve(x);
}
}
else {
resolve(x);
}
}
static resolve(value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise((resolve) => resolve(value));
}
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
}
限制最大请求数,最快请求完毕
假如等待请求接口1000个,限制每次只能发出100个。即同一时刻最多有100个正在发送的请求。每当100个之中有一个请求完成时,则从待请求的接口(即剩余的900个待请求接口)中再取出一个发出。保证当前并发度仍旧为100。直至全部接口请求完成。
let count = 0; // 当前正在运行的接口数量
const res = [] // 最后的结果
// 判断是否调度函数
const panDuan = (urls, max) => {
if (urls.length > 0 && count < max) {
resFn(urls, max)
}
}
// 做接口数据请求
const resFn = async (urls, max) => {
count++;
const prom = await new Promise((resolve, reject) => {
Promise.resolve(urls.shift()).then(value => {
res.push(value);
resolve(value)
}, reason => {
res.push(reason);
reject(reason)
})
})
prom.then(() => {
count--;
panDuan(urls, max)
})
}
// 循环处理
const fn1 = (urls, max) => {
for(let i = 0; i < max; i++) {
resFn(urls)
}
return res
}