不能做只会调用sdk的工具人

68 阅读3分钟

总结一下,前一段时间内写的一个需求的注意点。虽然仅仅是对一个封装好的sdk的调用,但是细挖的话,里面也有很多值得关注的点。写下来总结一下,不断进步!!!

首先来大概介绍一下需求,就是引入一个,已经封装好的客服sdk,功能就是可以实现,自动回复,以及转接人工这些。因为没有npm版本需要手动以script标签的形式。大概就是这样,下面分析我考虑不周的地方,以及遇到的问题。

first

首先呢,就是何时去初始化sdk.

这个sdk,在加载完毕之后会在window对象下面挂载一个函数(为了方便,这里我命名为fn),fn接收一个url 作为地址(url是iframe的url),fn接受一些钩子函数作为回调函数,在特定时机触发,返回一个promise,成功时resolve该sdk的实例,失败时reject sdk的错误信息。

他内部的ui以iframe形式展示,需要挂在到,dom实例上。

//初始化方法
window.fn({
      //
      target: document.getElementById('linkchatWrap'),
      //
      url: data,
      
      //下面是一些勾子函数
      showCallback: () => {
      },
      //展示时触发
      hideCallback: () => {
      },
      //隐藏时触发
      iframeOnloadCallback: () => {}
    });

我们需要在组件渲染之前,引入sdk,

  const handleLoadScript = () => {
    const myScript = document.createElement('script');
    myScript.src =
      'sdk的url';
    myScript.async = true;
    myScript.onload = handleLoad;
    document.body.appendChild(myScript);
  };

当然我们又不能影响html 的加载,这里必须采用async的形式。那么问题就来了,根据async的机制,对应资源加载好之后立即执行,此时html不一定渲染好。引用一下如下的图

image.png

我们需要保证在执行初始化时 script 一定加载完成了,那怎么去保证呢。利用script 标签上面的onload就可以保证。ok,我们只需要在一个useEffect里面去调用 handleLoadScript即可。 然后在 handleLoad事件中去执行初始化。

 const handleLoad = async () => {
    try {
      const data = await getUrl({ channel_id: 0 });
      const linkInstance = await handleInitialize(data);
      //初始化函数,调用初始化方法

    } catch (e: any) {
      //一些错误上报方式
    }
  };
  const handleInitialize = (data: string) => {
    return window.fn({
      target: document.getElementById('linkchatWrap'),
      url: data,
      //下面是一些勾子函数
      showCallback: () => {
      },
      //展示时触发
      hideCallback: () => {
      },
      //隐藏时触发
      iframeOnloadCallback: () => {}
    });
    
  };
  

如上所示,采用同步调用方式,需要先获取url ,再去调用,这个是必须要确保的。

到了这里,我们明确了script 加载的机制。以及何时去初始化。

second

那么接下来的问题,初始化完成后怎么去展示呢? 这个需求是,点击一个按钮去展示出来,并且可以拖拽移动位置。 好家伙,不就是一个modal组件吗。安排!拖拽就安利一个 react-draggable 库,挺好用的。利用fix 定位,使其对整个屏幕局中对齐。首先菜单栏里面有个在线客服,点击时候去展示sdk.

听起来很简单呀?并没有什么大问题。那么再仔细想想,仅仅就是去展示吗? 我们以一定是需要考虑一些错误情况。假如初始化没用成功怎么办?加入sdk引入失败怎么办?所以这个点击事件不仅要去展示,更要先去判断,是否可以展示。

  const handleClick = async () => {
    if (window.fn === undefined) {
      handleLoadScript();‘
      //没有引入成功就继续引入。
    } else {
      if (linkchat === undefined) {
      //没初始化,就先初始化。
        try {
          const data = await getUrl({ channel_id: 0 });
          const linkInstance = await handleInitialize(data);
          setlinkchat(linkInstance);
          linkInstance.show();
        } catch (e) {
           //省略错误处理
        }
      } else {
        fn.show();
        //正常就,调用展示。
      }
    }
  };

以上两点,是值得关注的点,当然还有一些注意点,对一些复用逻辑进行封装。比如初始化,比如引入sdk这些。

值得强调的还是一定要在开发过程中注意细节,优化逻辑,避免冗杂代码,考虑错误边界。先构思之后再动手,还有就是养成复盘习惯哦