假设我多次调用https
来检索数据,并且我想在最后一个请求的末尾调用函数formatJsonToLocale
。除了检查数组的最后一个元素外,是否有办法确定该请求何时结束。
let sheetsArray = []
function sheetsAsJsonById (ids) {
for (let i = 0; i < ids.length; i++) {
const queryUrl = `sheets.html`
https
.get(queryUrl, res => {
let stream = []
res
.on('data', function (data) {
stream.push(data)
})
.on('end', function () {
let data = Buffer.concat(stream)
data = JSON.parse(data)
sheetArrays.push(data['values'])
formatJsonToLocale(sheetsArray) // <----- call this one after last request
})
})
.on('error', err => {
console.error(`Error in response: ${err}`)
})
}
}
当我在函数外部调用formatJsonToLocale
时,我会遇到一个问题,即前一个函数可能无法完成,因为https
会异步处理内容。
关于如何处理此问题的任何建议?
答案 0 :(得分:1)
您需要跟踪在for循环中执行的异步代码(https.get
)的执行情况。这可以通过如下的诺言来实现:
let sheetsArray = []
function sheetsAsJsonById (ids) {
let promises = []
for (let i = 0; i < ids.length; i++) {
const queryUrl = `sheets.html`
promises.push(makeHTTPRequest(queryUrl))
}
Promise.all(promises).then((sheetArrays) => {
formatJsonToLocale(sheetsArray)
})
}
const makeHTTPRequest = (url) => {
return new Promise((resolve, reject) => {
https
.get(url, res => {
let stream = []
res
.on('data', function (data) {
stream.push(data)
})
.on('end', function () {
let data = Buffer.concat(stream)
data = JSON.parse(data)
resolve(data)
})
.on('error', err => {
console.error(`Error in response: ${err}`)
})
})
}
如果要坚持使用回调,可以使用async节点模块的async.each
函数。
答案 1 :(得分:0)
将import UIKit
import AVFoundation
import ImageDetect
class ViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
@IBOutlet weak var cameraView: UIView!
@IBOutlet weak var imgvew: UIImageView!
private var scanTimer: Timer?
var captureSession = AVCaptureSession()
var sessionOutput = AVCaptureStillImageOutput()
var previewLayer = AVCaptureVideoPreviewLayer()
var isBackCamera = true
var clickedImage: Data?
var captureDevice : AVCaptureDevice?
var imagePicker : UIImagePickerController!
override func viewDidLoad() {
}
override func viewWillAppear(_ animated: Bool) {
if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.authorized {
self.camera()
} else {
AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted :Bool) -> Void in
if granted == true
{
DispatchQueue.main.async {
self.camera()
}
}
else
{
// self.showPermistionAlert()
}
})
}
// camera()
scanTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(getImages), userInfo: nil, repeats: true)
}
func camera(){
self.tabBarController?.tabBar.isHidden = true
let devices = AVCaptureDevice.devices(for: AVMediaType.video)
for device in devices{
do{
let camera = getDevice(position: .front)
let input = try AVCaptureDeviceInput(device: camera!)
if captureSession.canAddInput(input){
captureSession.addInput(input)
sessionOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
if captureSession.canAddOutput(sessionOutput){
captureSession.startRunning()
captureSession.addOutput(sessionOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
previewLayer.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraView.layer.addSublayer(previewLayer)
previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2)
cameraView.contentMode = .scaleToFill
previewLayer.bounds = cameraView.frame
}
}
}
catch{
print("error")
}
}
}
@objc func getImages()
{
if let videoConnection = sessionOutput.connection(with: AVMediaType.video) {
sessionOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: {buffer, error in
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer!)
let captureimage = UIImage(data: imageData!)!
self.imgvew.image = captureimage
captureimage.detector.crop(type: .face) { result in
print(result)
switch result {
case .success(let faces):
print("Success")
case .notFound:
print("Notfound")
case .failure(let error):
print("Failure")
}
}
})
}
}
func getDevice(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
let devices: NSArray = AVCaptureDevice.devices() as NSArray;
for de in devices {
let deviceConverted = de as! AVCaptureDevice
if(deviceConverted.position == position){
return deviceConverted
}
}
return nil
}
}
包装在Promise中,它会解决https.get
事件,并拒绝出现任何错误。现在您可以等待promise,并且在for循环完成后调用函数
end