2015-06-07 44 views
5

我正在使用PromiseKit並希望強制順序下載JSON。 JSON的數量可能會發生變化。使用PromiseKit強制順序下載

我已閱讀關於鏈接的this。 如果我有固定數量的說3下載,這將是罰款。

但是,如果我想要下載的更改次數依次下載,該怎麼辦?

這是我的2個URL的代碼。我想知道如何在數組上迭代dateUrlArray[i]來做到這一點?

- (void)downloadJSONWithPromiseKitDateArray:(NSMutableArray *)dateUrlArray { 
    [self.operationManager GET:dateUrlArray[0] 
        parameters:nil] 
    .then(^(id responseObject, AFHTTPRequestOperation *operation) { 
     NSDictionary *resultDictionary = (NSDictionary *) responseObject; 
     Menu *menu = [JsonMapper mapMenuFromDictionary:resultDictionary]; 
     if (menu) { 
      [[DataAccess instance] addMenuToRealm:menu]; 
     } 
     return [self.operationManager GET:dateUrlArray[1] 
           parameters:nil]; 
    }).then(^(id responseObject, AFHTTPRequestOperation *operation) { 
     NSDictionary *resultDictionary = (NSDictionary *) responseObject; 

     Menu *menu = [JsonMapper mapMenuFromDictionary:resultDictionary]; 
     if (menu) { 
      [[DataAccess instance] addMenuToRealm:menu]; 
     } 
    }) 
    .catch(^(NSError *error) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self handleCatchwithError:error]; 
     }); 
    }).finally(^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      DDLogInfo(@".....finally"); 
     }); 
    }); 
} 

回答

4

你正在尋找的概念是then能夠鏈接。你想在for循環中鏈接多個promise。

我的Objective-C是真的生鏽 - 但它應該是這個樣子:

// create an array for the results 
__block NSMutableArray *results = [NSMutableArray arrayWithCapacity:[urls count]]; 
// create an initial promise 
PMKPromise *p = [PMKPromise promiseWithValue: nil]; // create empty promise 
for (id url in urls) { 
    // chain 
    p = p.then(^{ 
     // chain the request and storate 
     return [self.operationManager GET:url 
       parameters:nil].then(^(id responseObject, AFHTTPRequestOperation *operation) { 
       [results addObject:responseObject]; // reference to result 
       return nil; 
     }); 
    }); 
} 
p.then(^{ 
    // all results available here 
}); 
+0

很多很多謝謝你'生鏽的'ObjC ;-)好的答案,恕我直言,在Promisekit網站上的遺漏。我做了一個小編輯(p應該是PMKPromise類型)。 – brainray

3

對於我們這些尋找雨燕2.3解決方案:

import PromiseKit 

extension Promise { 
    static func resolveSequentially(promiseFns: [()->Promise<T>]) -> Promise<T>? { 
     return promiseFns.reduce(nil) { (fn1: Promise<T>?, fn2: (()->Promise<T>)?) -> Promise<T>? in 
      return fn1?.then({ (_) -> Promise<T> in 
       return fn2!() 
      }) ?? fn2!() 
     } 
    } 
} 

注意,這個函數如果promises數組爲空,則返回nil。使用的

下面是如何上傳附件的一個陣列中的序列的示例:

func uploadAttachments(attachments: [Attachment]) -> Promise<Void> { 
    let promiseFns = attachments.map({ (attachment: Attachment) -> (()->Promise<Void>) in 
     return { 
      return self.uploadAttachment(attachment) 
     } 
    }) 
    return Promise.resolveSequentially(promiseFns)?.then({}) ?? Promise() 
} 

func uploadAttachment(attachment: Attachment) -> Promise<Void> { 
    // Do the actual uploading 
    return Promise() 
} 
+0

非常感謝您的輸入!順便說一句:與此同時我用NSOperation解決這類任務wgich不需要第三方庫 – brainray

+0

感謝您的反饋,這完全有道理! – Vegard

2

感謝維加德的回答和我改寫爲夫特3:

extension Promise { 
    static func resolveSequentially(promiseFns: [()->Promise<T>]) -> Promise<T>? { 
     return promiseFns.reduce(nil) { (fn1: Promise<T>?, fn2: (()->Promise<T>)?) -> Promise<T>? in 
      return fn1?.then{ (_) -> Promise<T> in 
       return fn2!() 
      } ?? fn2!() 
     } 
    } 
} 



/* Example */ 
func uploadAttachments(_ attachments: [Attachment]) -> Promise<Void> { 
    let promiseFns = attachments.map({ (attachment: Attachment) -> (()->Promise<Void>) in 
     return { 
      return self. uploadAttachment(attachment) 
     } 
    }) 

    return Promise.resolveSequentially(promiseFns: promiseFns)?.then{Void -> Void in} ?? Promise { Void -> Void in } 
}