UNPKG

@uiw/react-baidu-map-api-loader

Version:

Baidu Map api-loader Components for React.

164 lines (162 loc) 4.54 kB
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; /// <reference types="@uiw/react-baidu-map-types" /> /** * 初始化和加载baidu地图 */ import React from 'react'; import { requireScript } from '@uiw/react-baidu-map-utils'; import { jsx as _jsx } from "react/jsx-runtime"; export function delay(time) { return new Promise((resolve, reject) => { window && window.setTimeout(resolve, time); }); } var DEFAULT_RETRY_TIME = 3; /** * APILoader 用于加载百度地图依赖 */ export default class APILoader extends React.Component { /** * 等待BMap就绪 */ static ready() { return _asyncToGenerator(function* () { if (window && window.BMap.Map) { return; } if (window && window.BMapGL.Map) { return; } return new Promise((res, rej) => { APILoader.waitQueue.push([res, rej]); }); })(); } constructor(props) { super(props); this.isMountedOk = false; this.handleError = error => { if (this.isMountedOk) { this.setState({ error }); } }; this.finish = () => { if (window && this.props.type === 'webgl') { window.BMap = window.BMapGL; } if (this.isMountedOk) { this.setState({ loaded: true }); } }; this.state = { loaded: props.type === 'webgl' ? window && !!window.BMapGL && !!window.BMapGL.Map : window && !!window.BMap && !!window.BMap.Map }; if (this.props.akay == null) { throw new TypeError('BaiDuMap: akay is required'); } } componentDidMount() { this.isMountedOk = true; var { callbackName } = this.props; if (!window || !callbackName) { return; } if (this.props.type === 'webgl' && window && window.BMapGL && !window.BMapGL.Map || this.props.type === 'webgl' && window && !window.BMapGL || window && window.BMap && !window.BMap.Map || window && !window.BMap) { if (window && window[callbackName]) { APILoader.waitQueue.push([this.finish, this.handleError]); return; } this.loadMap(); } } componentWillUnmount() { this.isMountedOk = false; } render() { if (window && window.BMapGL && this.props.type === 'webgl') { window.BMap = window.BMapGL; } return this.state.loaded ? this.props.children : this.props.fallback ? this.props.fallback(this.state.error) : this.state.error ? /*#__PURE__*/_jsx("div", { style: { color: 'red' }, children: this.state.error.message }) : null; } getScriptSrc() { var cfg = this.props; var protocol = cfg.protocol || window.location.protocol; if (protocol.indexOf(':') === -1) { protocol += ':'; } var args = ["v=" + cfg.version, "ak=" + cfg.akay, "callback=" + cfg.callbackName]; if (cfg.type) { args.push("type=" + cfg.type); } return protocol + "//" + cfg.hostAndPath + "?" + args.join('&'); } /** * load BaiduMap in script tag */ loadMap() { var _this = this; return _asyncToGenerator(function* () { var { callbackName } = _this.props; if (!window || !callbackName) { return; } var src = _this.getScriptSrc(); window[callbackName] = () => { // flush queue var queue = APILoader.waitQueue; APILoader.waitQueue = []; queue.forEach(task => task[0]()); _this.finish(); }; var _loop = function* _loop() { try { yield requireScript(src); return 0; // break } catch (error) { if (i === DEFAULT_RETRY_TIME - 1) { var err = new Error("Failed to load Baidu Map: " + error.message); // flush queue var queue = APILoader.waitQueue; APILoader.waitQueue = []; queue.forEach(task => task[1](err)); _this.handleError(err); return { v: void 0 }; } yield delay(i * 1000); } }, _ret; for (var i = 0; i < DEFAULT_RETRY_TIME; i++) { _ret = yield* _loop(); if (_ret === 0) break; if (_ret) return _ret.v; } })(); } } APILoader.defaultProps = { akay: '', hostAndPath: 'api.map.baidu.com/api', version: '2.0', callbackName: 'load_bmap_sdk', type: '' }; /** * 全局可能存在多个Loader同时渲染, 但是只能由一个负责加载 */ APILoader.waitQueue = [];