While Loop 在 Promisekit 完成运行并在 Swift 中返回正确的值之前递增并重新运行

Posted

技术标签:

【中文标题】While Loop 在 Promisekit 完成运行并在 Swift 中返回正确的值之前递增并重新运行【英文标题】:While Loop increments and re-runs before Promisekit can finish running and return the proper value in Swift 【发布时间】:2016-09-10 17:07:19 【问题描述】:

我正在尝试使用带有 Alamofire 的 Promisekit 的 while 循环来链接四个 GET 请求,返回一个值,然后使用新参数重新运行四个请求。这是我正在使用的当前代码:

        var index = 0
        var count = classDictionary["class"]!.count-1

        while index <= count 

        firstly 
            parseBooksXML(index)
            .then  abrevCode in
                self.parseBooksXML2(index, key: abrevCode)
            .then  courseNumber in
                self.parseBooksXML3(index, key: courseNumber)
            .then  instructorCode in
                self.parseBooksXML4(instructorCode)
            
            index += 1
        

前三个函数中的每一个都返回一个承诺的字符串值,然后将其传递给下一个函数,直到第四个也是最后一个函数调用另一个函数来使用 Kanna 解析下载的 html

理想情况下,我希望调用并完成所有四个函数,之后索引将递增并使用新的索引号再次运行循环。需要注意的是,传递给函数的索引是一种识别数组中的哪个索引值应该与哪个索引进行比较的方法。

为清楚起见,我在下面包含了 parseBooksXML 函数的代码:

func parseBooksXML(index: Int) -> Promise<String> 
    return Promise fulfill, reject in

    let headers = [
        "Referer": "URL"
    ]


    Alamofire.request(.GET, "URL", headers: headers)
        .responseData  response in

            switch response.result 
            case .Success:
                let xml = SWXMLHash.parse(response.data!)

                do 

                    let range = self.classDictionary["class"]![index].rangeOfString("[a-zA-Z]2,4", options: .RegularExpressionSearch)
                    let result = self.classDictionary["class"]![index].substringWithRange(range!)

                    try self.abrevCode = (xml["departments"]["department"].withAttr("abrev", result).element!.attribute(by: "id")!.text)

                
                catch 
                    print("Error: \(error)")

                
                fulfill(self.abrevCode)

            case .Failure(let error):
                print(error)
            
        
    


func parseBooksXML2(index: Int, key: String) -> Promise<String> 
    return Promise fulfill, reject in

        let headers = [
        "Referer": "URL"
    ]


    Alamofire.request(.GET, "URL", headers: headers)
        .responseData  response in

            switch response.result 
            case .Success:
                let xml = SWXMLHash.parse(response.data!)
                 do 

                    let range = self.classDictionary["class"]![index].rangeOfString("\\d\\d\\d", options: .RegularExpressionSearch)
                    let result = self.classDictionary["class"]![index].substringWithRange(range!)

                    try self.courseNumber = (xml["courses"]["course"].withAttr("name", result).element?.attribute(by: "id")?.text)!

                 
                 catch 
                    print("Error: \(error)")

                
                fulfill(self.courseNumber)

            case .Failure(let error):
                print(error)
            

        
    


func parseBooksXML3(index: Int, key: String) -> Promise<String> 
    return Promise fulfill, reject in

        let headers = [
        "Referer": "URL"
    ]

    Alamofire.request(.GET, "URL", headers: headers)
        .responseData  response in

            switch response.result 
            case .Success:
                let xml = SWXMLHash.parse(response.data!)
                do 

                    let range = self.classDictionary["class"]![index].rangeOfString("[a-zA-Z]1,3?\\d?\\d?\\d?$", options: .RegularExpressionSearch)
                    let result = self.classDictionary["class"]![index].substringWithRange(range!)

                    try self.instructorCode = (xml["sections"]["section"].withAttr("instructor", self.classTeacher[index]).element?.attribute(by: "id")?.text)!
                
                catch 
                    print("Error: \(error)")


                
                fulfill(self.instructorCode)

            case .Failure(let error):
                print(error)
            

        
    


func parseBooksXML4(key: String) -> Void 

        let headers = [
        "Referer": "URL"
    ]

    Alamofire.request(.GET, "URL", headers: headers)
        .responseData  response in

            switch response.result 
            case .Success:
                self.parseISBN(String(data: response.data!, encoding: NSUTF8StringEncoding)!)

            case .Failure(let error):
                print(error)
            

        
    

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

你需要使用when:

let count = classDictionary["class"]!.count-1

let promises = (0..<count).map  index -> Promise<ReplaceMe> in
    return firstly 
        parseBooksXML(index)
    .then  abrevCode in
        self.parseBooksXML2(index, key: abrevCode)
    .then  courseNumber in
        self.parseBooksXML3(index, key: courseNumber)
    .then  instructorCode in
        self.parseBooksXML4(instructorCode)
    


when(fulfilled: promises).then 
    //…

【讨论】:

【参考方案2】:

由于 parseBooksXML4 调用是异步的,您应该包装 parseBooksXML4() 调用以返回 promise 并等待其完成,然后再增加索引。

    firstly 
        parseBooksXML(index)
        .then  abrevCode in
            self.parseBooksXML2(index, key: abrevCode)
        .then  courseNumber in
            self.parseBooksXML3(index, key: courseNumber)
        .then  instructorCode in
            self.parseBooksXML4(instructorCode)
        .then  _ in
            index += 1
        
    

【讨论】:

嘿,感谢您的输入,但我尝试将 parseBooksXML4 包装在 Promise 中: func parseBooksXML4(key: String) -> Promise return Promise fulfill, reject in我使用了您发布的代码,但现在似乎“首先”部分中的任何内容都没有被调用。有什么想法吗?

以上是关于While Loop 在 Promisekit 完成运行并在 Swift 中返回正确的值之前递增并重新运行的主要内容,如果未能解决你的问题,请参考以下文章

C++中,do while, for loop和while loop之间有啥不同

数据库--循环语句:while loop/end loop

“Do While”“Loop”和“While”“Wend”循环。有啥不同?

Python里的while loop

VB中的do while……loop 和do……loop while语句是一样的吗

java 初级while loop的错误