#Define XMLHTTP "MSXML2.ServerXMLHTTP.6.0"
Local loRequests
loRequests = Createobject("Requests")
Clear
_Screen.FontName="Courier New"
Local lnStartSeconds
lnStartSeconds = Seconds()
Local lnI, loRequest
For lnI = 1 To 10
loRequest = loRequests.CreateRequest("GET","[URL unfurl="true"]https://api.publicapis.org/random","StoreAPIs")[/URL]
* add request header, etc.
loRequest.Send()
Endfor
? '****************************'
? '* Done sending 10 requests *'
? '****************************'
* The responses will come in and get caught in the Timer() event of loRequests
* Which requires loRequests to stay resident in memory (be in scope)
* after the code finishes already here
* Therefore a wait loop.
Do while loRequests.oRequests.count>0
Doevents
EndDo
?
? 'Overall time:'+Transform(Seconds()-lnStartSeconds)
* You may instead add loRequests to your goAPP or _screen, and do nothing
* The timer and callback mechanism will work on the responses.
* Callback function (could also use a method of an object)
Function StoreAPIs(lcResponse)
If !Used("APIs")
*In the demo store api results into a cursor
Create Cursor APIs (API M, Description M, Link M, Category M)
Browse Nowait
Endif
Local loNFjson,loAPI
loNFjson = nfjsonread(lcResponse) && this uses nfjsonread.prg of Marco Plaza's nfjson
* specifically for api.publicapis.org/random I know this has 1 entry per result
loAPI = loNFjson.entries[1]
* get nfjson from [URL unfurl="true"]https://github.com/VFPX/nfJson[/URL]
* copy nfjsonread.prg into the same directory as this prg and CD into it
* before starting all this.
* Alternatively, use this simple parsing:
* loAPI = CreateObject('Empty')
* AddProperty(loAPI,"API",StrExtract(lcResponse,["API":"],["]))
* AddProperty(loAPI,"Description",StrExtract(lcResponse,["Description":"],["]))
* AddProperty(loAPI,"Link",StrExtract(lcResponse,["Link":"],["]))
* AddProperty(loAPI,"Category",StrExtract(lcResponse,["Category":"],["]))
If Not Isnull(loAPI)
Insert Into APIs Values (loAPI.API, loAPI.Description, loAPI.Link, loAPI.Category)
? loAPI.API, loAPI.Link, loAPI.Category
? loAPI.Description
Endif
EndFunc
* General async requests handling
Define Class Requests As Timer
Interval = 100
oRequests = .Null.
Procedure Init()
This.oRequests = Createobject("Collection")
Endproc
Procedure CreateRequest(cMethod, cURL, cCallback)
Local loRequest
loRequest = Createobject(XMLHTTP)
loRequest.Open(cMethod,cURL,.T.)
AddProperty(loRequest,"cCallback",Evl(cCallback,"This.DefaultProcessing"))
AddProperty(loRequest,"nInitialseconds",Seconds())
This.oRequests.Add(loRequest)
Return loRequest
Endproc
Procedure DefaultProcessing(cResponseText)
*...whatever would suit here
* usually, you need specific handling for specific API results
*so you'd make use of the callback parameter of the CreateRequest method
Endproc
Procedure Timer()
Local loRequest
For lnItem = This.oRequests.Count To 1 Step -1
loRequest = This.oRequests.Item(lnItem)
If loRequest.readystate=4
?
? 'Response after creation of the request in seconds: '+Transform(Seconds()-loRequest.nInitialseconds)
Local lcCallback
lcCallback = loRequest.cCallback
&lcCallback(loRequest.ResponseText)
This.oRequests.Remove(lnItem)
Endif
Endfor
Endproc
Enddefine