promise.ts 2.4 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2
import { isFunction } from '@vue/shared'

fxy060608's avatar
fxy060608 已提交
3
import { invokeApi, handlePromise, wrapperReturnValue } from '@dcloudio/uni-api'
fxy060608's avatar
fxy060608 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/

const CONTEXT_API_RE = /^create|Manager$/

// Context例外情况
const CONTEXT_API_RE_EXC = ['createBLEConnection']

const TASK_APIS = ['request', 'downloadFile', 'uploadFile', 'connectSocket']

// 同步例外情况
const ASYNC_API = ['createBLEConnection']

const CALLBACK_API_RE = /^on|^off/

export function isContextApi(name: string) {
  return CONTEXT_API_RE.test(name) && CONTEXT_API_RE_EXC.indexOf(name) === -1
}
export function isSyncApi(name: string) {
  return SYNC_API_RE.test(name) && ASYNC_API.indexOf(name) === -1
}

export function isCallbackApi(name: string) {
  return CALLBACK_API_RE.test(name) && name !== 'onPush'
}

export function isTaskApi(name: string) {
  return TASK_APIS.indexOf(name) !== -1
}

export function shouldPromise(name: string) {
  if (isContextApi(name) || isSyncApi(name) || isCallbackApi(name)) {
    return false
  }
  return true
}

/* eslint-disable no-extend-native */
if (!Promise.prototype.finally) {
43
  Promise.prototype.finally = function (
fxy060608's avatar
fxy060608 已提交
44 45 46 47
    onfinally?: (() => void) | undefined | null
  ) {
    const promise = this.constructor as PromiseConstructor
    return this.then(
48 49
      (value) => promise.resolve(onfinally && onfinally()).then(() => value),
      (reason) =>
fxy060608's avatar
fxy060608 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63
        promise.resolve(onfinally && onfinally()).then(() => {
          throw reason
        })
    )
  }
}

export function promisify(name: string, api: unknown) {
  if (!shouldPromise(name)) {
    return api
  }
  if (!isFunction(api)) {
    return api
  }
fxy060608's avatar
fxy060608 已提交
64
  return function promiseApi(options: Record<string, any> = {}) {
fxy060608's avatar
fxy060608 已提交
65 66 67 68 69
    if (
      isFunction(options.success) ||
      isFunction(options.fail) ||
      isFunction(options.complete)
    ) {
fxy060608's avatar
fxy060608 已提交
70
      return wrapperReturnValue(name, invokeApi(name, api, options))
fxy060608's avatar
fxy060608 已提交
71 72 73 74 75 76 77 78 79 80
    }
    return wrapperReturnValue(
      name,
      handlePromise(
        new Promise((resolve, reject) => {
          invokeApi(
            name,
            api,
            Object.assign({}, options, {
              success: resolve,
81
              fail: reject,
fxy060608's avatar
fxy060608 已提交
82
            })
fxy060608's avatar
fxy060608 已提交
83 84 85 86 87 88
          )
        })
      )
    )
  }
}