Promise相关

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
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在 javascript 中, 所有代码都是单线程执行的。 由于这个缺陷,导致 javascript 的所有网络操...
    Robot_Lee阅读 598评论 0 0
  • 可供参考资料 1、了解 Promise 吗? 了解Promise,Promise是一种异步编程的解决方案,有三种状...
    coderfl阅读 262评论 0 0
  • 异步编程 *fs文件操作*数据库操作*ajax*定时器在promise之前的解决方式: 旧的解决方法:必须在启动异...
    Spinach阅读 474评论 0 2
  • Promise 检测图片 检测图片是否加载成功,成功就正常显示,失败就展示默认图片 休眠的实现方法 基本用法 有一...
    池鱼_故渊阅读 266评论 0 1
  • 0、底层 Event Loop事件循环:就是一个执行消息队列的机制 宏任务 微任务为了解决这种情况,将任务分为了同...
    月光一族阅读 2,919评论 7 42