1 | import {
|
2 | onAndSyncApis,
|
3 | noPromiseApis,
|
4 | otherApis,
|
5 | initPxTransform,
|
6 | Link
|
7 | } from '@tarojs/taro'
|
8 |
|
9 | const RequestQueue = {
|
10 | MAX_REQUEST: 5,
|
11 | queue: [],
|
12 | pendingQueue: [],
|
13 |
|
14 | request (options) {
|
15 | this.queue.push(options)
|
16 | return this.run()
|
17 | },
|
18 |
|
19 | run () {
|
20 | if (!this.queue.length) return
|
21 |
|
22 | while (this.pendingQueue.length < this.MAX_REQUEST) {
|
23 | const options = this.queue.shift()
|
24 | let successFn = options.success
|
25 | let failFn = options.fail
|
26 | options.success = (...args) => {
|
27 | this.pendingQueue = this.pendingQueue.filter(item => item !== options)
|
28 | this.run()
|
29 | successFn && successFn.apply(options, args)
|
30 | }
|
31 | options.fail = (...args) => {
|
32 | this.pendingQueue = this.pendingQueue.filter(item => item !== options)
|
33 | this.run()
|
34 | failFn && failFn.apply(options, args)
|
35 | }
|
36 | this.pendingQueue.push(options)
|
37 | return swan.request(options)
|
38 | }
|
39 | }
|
40 | }
|
41 |
|
42 | function taroInterceptor (chain) {
|
43 | return request(chain.requestParams)
|
44 | }
|
45 |
|
46 | const link = new Link(taroInterceptor)
|
47 |
|
48 | function request (options) {
|
49 | options = options || {}
|
50 | if (typeof options === 'string') {
|
51 | options = {
|
52 | url: options
|
53 | }
|
54 | }
|
55 | const originSuccess = options['success']
|
56 | const originFail = options['fail']
|
57 | const originComplete = options['complete']
|
58 | let requestTask
|
59 | const p = new Promise((resolve, reject) => {
|
60 | options['success'] = res => {
|
61 | originSuccess && originSuccess(res)
|
62 | resolve(res)
|
63 | }
|
64 | options['fail'] = res => {
|
65 | originFail && originFail(res)
|
66 | reject(res)
|
67 | }
|
68 |
|
69 | options['complete'] = res => {
|
70 | originComplete && originComplete(res)
|
71 | }
|
72 |
|
73 | requestTask = RequestQueue.request(options)
|
74 | })
|
75 | p.abort = (cb) => {
|
76 | cb && cb()
|
77 | if (requestTask) {
|
78 | requestTask.abort()
|
79 | }
|
80 | return p
|
81 | }
|
82 | return p
|
83 | }
|
84 |
|
85 | function processApis (taro) {
|
86 | const weApis = Object.assign({ }, onAndSyncApis, noPromiseApis, otherApis)
|
87 | Object.keys(weApis).forEach(key => {
|
88 | if (!(key in swan)) {
|
89 | taro[key] = () => {
|
90 | console.warn(`百度小程序暂不支持 ${key}`)
|
91 | }
|
92 | return
|
93 | }
|
94 | if (!onAndSyncApis[key] && !noPromiseApis[key]) {
|
95 | taro[key] = (options, ...args) => {
|
96 | options = options || {}
|
97 | let task = null
|
98 | let obj = Object.assign({}, options)
|
99 | if (typeof options === 'string') {
|
100 | if (args.length) {
|
101 | return swan[key](options, ...args)
|
102 | }
|
103 | return swan[key](options)
|
104 | }
|
105 | const p = new Promise((resolve, reject) => {
|
106 | ['fail', 'success', 'complete'].forEach((k) => {
|
107 | obj[k] = (res) => {
|
108 | options[k] && options[k](res)
|
109 | if (k === 'success') {
|
110 | if (key === 'connectSocket') {
|
111 | resolve(
|
112 | Promise.resolve().then(() => Object.assign(task, res))
|
113 | )
|
114 | } else {
|
115 | resolve(res)
|
116 | }
|
117 | } else if (k === 'fail') {
|
118 | reject(res)
|
119 | }
|
120 | }
|
121 | })
|
122 | if (args.length) {
|
123 | task = swan[key](obj, ...args)
|
124 | } else {
|
125 | task = swan[key](obj)
|
126 | }
|
127 | })
|
128 | if (key === 'uploadFile' || key === 'downloadFile') {
|
129 | p.progress = cb => {
|
130 | if (task) {
|
131 | task.onProgressUpdate(cb)
|
132 | }
|
133 | return p
|
134 | }
|
135 | p.abort = cb => {
|
136 | cb && cb()
|
137 | if (task) {
|
138 | task.abort()
|
139 | }
|
140 | return p
|
141 | }
|
142 | }
|
143 | return p
|
144 | }
|
145 | } else {
|
146 | taro[key] = (...args) => {
|
147 | const argsLen = args.length
|
148 | const newArgs = args.concat()
|
149 | const lastArg = newArgs[argsLen - 1]
|
150 | if (lastArg && lastArg.isTaroComponent && lastArg.$scope) {
|
151 | newArgs.splice(argsLen - 1, 1, lastArg.$scope)
|
152 | }
|
153 | return swan[key].apply(swan, newArgs)
|
154 | }
|
155 | }
|
156 | })
|
157 | }
|
158 |
|
159 | function pxTransform (size) {
|
160 | const {
|
161 | designWidth = 750,
|
162 | deviceRatio = {
|
163 | '640': 2.34 / 2,
|
164 | '750': 1,
|
165 | '828': 1.81 / 2
|
166 | }
|
167 | } = this.config || {}
|
168 | if (!(designWidth in deviceRatio)) {
|
169 | throw new Error(`deviceRatio 配置中不存在 ${designWidth} 的设置!`)
|
170 | }
|
171 | return parseInt(size, 10) / deviceRatio[designWidth] + 'rpx'
|
172 | }
|
173 |
|
174 | export default function initNativeApi (taro) {
|
175 | processApis(taro)
|
176 | taro.requestPayment = taro.requestPolymerPayment
|
177 | taro.request = link.request.bind(link)
|
178 | taro.addInterceptor = link.addInterceptor.bind(link)
|
179 | taro.cleanInterceptors = link.cleanInterceptors.bind(link)
|
180 | taro.getCurrentPages = getCurrentPages
|
181 | taro.getApp = getApp
|
182 | taro.initPxTransform = initPxTransform.bind(taro)
|
183 | taro.pxTransform = pxTransform.bind(taro)
|
184 | }
|