資源請(qǐng)求
這陣子要發(fā)布qq小游戲了 , 沒(méi)想到剛上來(lái)就翻車了...直接請(qǐng)求資源的時(shí)候就炸了:
報(bào)錯(cuò)如下:
VM696:263 createDownloadTask:fail exceed max download connection count
查了下文檔 , 說(shuō)是一次請(qǐng)求不能超過(guò)10個(gè)...(資源超過(guò)10M的一般都超過(guò)10個(gè)吧??);
各種找, 最后還是得去微信小程序社區(qū)找方案, 兜兜轉(zhuǎn)轉(zhuǎn)又跑去github弄了個(gè)輪子,
簡(jiǎn)而言之就是做個(gè)隊(duì)列, 反正每次請(qǐng)求不能超過(guò)10個(gè),超過(guò)了就老實(shí)呆著排隊(duì),等一下再說(shuō):
并發(fā)限制文檔傳送門
先上github上面輪子的鏈接:
嗯...這個(gè)輪子有點(diǎn)古老,不能直接用, 而且是用在微信小程序上面的, 所以我得改造一下,廢話少說(shuō)上代碼:
//index.js
import q from './queue'
function queueRequest(request, concurrency = 10) {
if (typeof request !== 'function') {
throw Error('request must be function')
}
const queue = q((task, callback) => task(callback), concurrency)
return (obj) => {
queue.push((callback) => {
const originComplete = obj.complete
obj.complete = (...args) => {
callback()
if (typeof originComplete === 'function') {
originComplete(...args)
}
}
request(obj)
})
}
}
//在老輪子的基礎(chǔ)上,在這里加了點(diǎn)東西,因?yàn)槭莇ownloadFile不給力...qq小游戲的api跟微信部分的是通用的,你懂的,順手一起弄上去了
function queue(concurrency) {
const request = wx.request
Object.defineProperty(wx, 'request', {
get() {
return queueRequest(request, concurrency)
}
})
const QQrequest =qq.request;
Object.defineProperty(qq, 'request', {
get() {
return queueRequest(QQrequest, concurrency)
}
})
const wxDownloadFile = wx.downloadFile ;
Object.defineProperty(wx, 'downloadFile', {
get() {
return queueRequest(wxDownloadFile, concurrency)
}
})
const qqDownloadFile = qq.downloadFile ;
Object.defineProperty(qq, 'downloadFile', {
get() {
return queueRequest(qqDownloadFile, concurrency)
}
})
}
export {
queueRequest,
queue,
}
然后在打包好的 小游戲項(xiàng)目里面的 game.js (因?yàn)槭切∮螒?所以是game.js,如果是小程序,那就應(yīng)該是app.js)里面,加上這么兩句調(diào)用一下:
//game.js
import { queue } from './queue/index.js'
queue(10);
嗯哼,這樣就大功告成啦,但是每次打包完都要手動(dòng)復(fù)制和加那么兩句話,實(shí)在是讓人無(wú)語(yǔ),本著程序猿懶惰的美德, 再弄個(gè)自動(dòng)復(fù)制粘貼添加兩行代碼的 python 文件:
##copyqueue.py 說(shuō)明一下, 這里是用的python3
import os, shutil
from os import path
def copyFiles(source, target):
if source is None or source is "":
raise FileNotFoundError("源文件夾不能為空")
if not path.exists(target):
os.makedirs(target) # 創(chuàng)建目標(biāo)文件夾
if path.isfile(source): # 源目錄是文件
shutil.copy(source, target)
else:
target = path.join(target, path.split(source)[1])
if not path.exists(target):
os.makedirs(target) # 創(chuàng)建目標(biāo)文件夾
for file in os.listdir(source):
newFile = path.join(source, file)
if path.isfile(newFile):
shutil.copy(newFile, target)
else:
copyFiles(newFile, target)
target = 'F:\\*****\\wechatgame' #此處星號(hào)為省略路徑,用你自己的真實(shí)路徑就好了
source = 'F:\\*****\\queue' #此處星號(hào)為省略路徑,用你自己的真實(shí)路徑就好了
copyFiles(source,target)
# coding=UTF-8
filename = 'F:\\*****\wechatGame\\game.js'#此處星號(hào)為省略路徑,用你自己的真實(shí)路徑就好了
with open(filename, 'a') as file_object:
file_object.write("\n\n")
file_object.write("import { queue } from './queue/index.js'\n")
file_object.write("queue(9);\n")
嗯哼,然后打包成exe 或者直接弄個(gè)bat文件執(zhí)行以下 , 就ok了,下次雙擊就可以了~ ~(或者你其實(shí)也可以弄個(gè)插件,打包的時(shí)候順便打包進(jìn)去,時(shí)間有限我就不贅述啦);
想了想,我還是干脆把另外一個(gè)文件也copy進(jìn)來(lái)給大家好了,到時(shí)候直接復(fù)制粘貼就能用了這輪子:
//queue.js
const checkConcurrency = (concurrency = 1) => {
if (concurrency == null) {
concurrency = 1
}
else if (concurrency === 0) {
throw new Error('Concurrency must not be zero')
}
return concurrency
}
const onlyOnce = (fn) => (...args) => {
if (fn === null) {
throw new Error('Callback was already called')
}
const callFn = fn
fn = null
return callFn(...args)
}
export default function queue(callback, concurrency) {
checkConcurrency(concurrency)
// 待處理的隊(duì)列
let workers = []
// 正在處理的隊(duì)列
const workerList = []
return {
concurrency,
push(task, callback) {
workers.push({
task,
callback,
})
setTimeout(() => {
this.process()
}, 0)
},
process() {
while (this.concurrency > workerList.length && workers.length) {
const worker = workers.shift()
workerList.push(worker)
callback(worker.task, onlyOnce((...args) => {
this.pull(worker)
if (typeof worker.callback === 'function') {
worker.callback(...args)
}
this.process()
}))
}
},
pull(worker) {
const index = workerList.indexOf(worker)
if (index !== -1) {
workerList.splice(index, 1)
}
}
}
}
好了,今天先到這兒了,有什么疑問(wèn)的話歡迎隨時(shí)交流~ 謝謝!! (另外,您有空也可以 上github的原輪子主人那里點(diǎn)個(gè)星星,哈哈哈哈,飲水不忘挖井人嘛~)
祝安好~ ~ O(∩_∩)O