import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="研发文档/FAQ" />

## flow中如何维护全局数据？

可以在项目入口函数`onStart`中给flow定义变量，这样在整个流程编排时都能拿到该变量。

```javascript

// 流程入口
export async function onStart() {
  // ...
  flow.globalData = {
    barcode: 'test'
  };
  // ...
}

// 某个具体流程
export default async function scanItem(data, flow) {
  // ...
  const { barcode } = flow.globalData;
  console.log(barcode);
  // ...
}

```

## 页面和弹窗定义了相同的热键，事件是否会同时触发？

不会，我们在引擎/组件层维护了事件堆栈，优先触发最上层的事件，开发者无需感知，正常开发即可。


## 扫码组件处于激活态的情况下唤起了弹窗，弹窗关闭后扫码组件仍然处于激活态，如何解决？

由于react的diff算法本身做的渲染优化，弹窗唤起与关闭时其余组件不会重新渲染，遇到强制渲染的场景需要手动给组件维护key（可以是随机数也可以是引擎传递的序列值）.

```javascript

<OPScan
  key={Math.random()}
  {...props}
/>

```

## 每次请求时都要手动catch否则会中断渲染进程，是否有统一处理方式？

有，你可以在函数顶层手动对报错处理进行封装，也可以使用官方提供的whileTry函数进行处理，例如：
```javascript

async function whileTry(fn) {
  let errorCount = 0;
  let preErrorTime = 0;
  while (true) {
    try {
      const ret = await fn();
      //只有返回不为undefined 的数据才能跳出循环
      if(ret !== undefined){
        return ret;
      }
    } catch (e) {
      console.error(e);
      // 100毫秒内的报错。累加到报错统计中
      if((Date.now() - preErrorTime) < 100){
        errorCount++;
      }
      preErrorTime = Date.now();
      // 端时间内计报错10次， 触发错误弹窗, 或非自定义错误
      if(errorCount > 10 || isSystemError(e)){
        errorCount = 0;
        await this.overlay("/system/alert", {title: e.message, okText: "重试"});
      }else{
        const message = e.message.split("\n");
        await this.toast('/system/toast', {
          // title: e.message, //'错误',
          message: e.message,
        });
      }
    }
  }
}

export default async function scanWaybill(data, flow) {
  return flow.whileTry(async function(){
    // 在whileTry里处理业务逻辑
    return flow.replay(ret.data);
  });

}

```