Promise.resolve 小技巧

902 阅读1分钟

1. 制作一个可以监听结束的动画

稍加修饰你就可以实现暂停效果
function createAnimation ({ duration = 300, update }) {
    let start =  0;
    let elapsed = 0;
    let progress = 0;
    let animationFrameId = 0;
  
    update = (typeof update === 'function') ? update : function () {};

    return new Promise((resolve, reject) => {
        // Start a new animation by requesting for an animation frame
        animationFrameId = requestAnimationFrame(
            function _animation (timestamp) {
                animationFrameId = requestAnimationFrame(_animation);
                // Set the animation start timestamp if not set
                if (!start) start = timestamp;
            
                // Compute the time elapsed and the progress (0 - 1)
                elapsed = timestamp - start;
                progress = Math.min(elapsed / duration, 1);
            
                // Call the `update()` callback with the current progress
                update(easeOut(progress));
                // Request another animation frame until duration elapses
                if (timestamp >= start + duration) {
                    cancelAnimationFrame(animationFrameId);
                    animationFrameId = 0;
                    resolve();
                }
            }
        );
    })
}

2. react 获取组件实例并防止重复创建相同类型实例

function getComponent(type) {
    return new Promise(resolve => {
      const component = components[type]
      if (component) {
        resolve(component)
      } else {
        ReactDOM.render(
          <Container
            ref={comp => {
              components[type] = comp
              resolve(comp)
            }}
            onDestory={destroy.bind(null, type)}
          />,
          getElement(type)
        )
      }
    })
}

3. jsonp的实现

function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) => {
    // 创建一个临时的 script 标签用于发起请求
    const script = document.createElement('script');
    // 将回调函数临时绑定到 window 对象,回调函数执行完成后,移除 script 标签
    window[callback] = data => {
      resolve(data);
      document.body.removeChild(script);
    };
    // 构造 GET 请求参数,key=value&callback=callback
    const formatParams = { ...params, callback };
    const requestParams = Object.keys(formatParams)
      .reduce((acc, cur) => {
        return acc.concat([`${cur}=${formatParams[cur]}`]);
      }, [])
            .join('&');
        // 构造 GET 请求的 url 地址
    const src = `${url}?${requestParams}`;
    script.setAttribute('src', src);
    document.body.appendChild(script);
  });
}

4. 图片懒加载

window.onload = function() {
  let imgs = document.querySelectorAll('#picList img')
  let getTop = function(e) {
    return e.offsetTop
  }
  let lazyLoadImg = function(picList) {
    let height = window.innerHeight
    let scollHeight =
      document.documentElement.scrollTop || document.body.scrollTop
    let loadProimise = function(path) {
      return new Promise((resolve, reject) => {
        let image = new Image()
        image.src = path
        image.onload = function() {
          resolve()
        }
        image.onerror = function() {
          reject('图片加载失败')
        }
      })
    }
    for (let i = 0; i < picList.length; i++) {
      if (height + scollHeight > getTop(picList[i])) {
        let path = picList[i].getAttribute('data-src')
        console.log(path)
        loadProimise(path)
          .then(() => {
            picList[i].src = path
          })
          .catch(err => {
            console.log(err)
          })
      }
    }
  }
  lazyLoadImg(imgs)
  window.onscroll = function() {
    lazyLoadImg(imgs)
  }
}

5. Await 类型检测

type Await<T extends (...args: any) => any> = T extends (
    ...args: any
  ) => Promise<infer U>
    ? U
    : T extends (...args: any) => infer U
    ? U
    : any;
  
    
  async function load() {
    return fetch("...");
  }
    
  type Thing = Await<typeof load>;