     
     // MARK: - Functions
     // Make preview
-    open func preview(_ text: String!, onSuccess: @escaping (Response) -> Void, onError: @escaping (PreviewError) -> Void) {
+    @discardableResult open func preview(_ text: String!, onSuccess: @escaping (Response) -> Void, onError: @escaping (PreviewError) -> Void) -> () -> Void {
+        
+        let cancellable = Cancellable()
+        
         let successResponseQueue = { (response: Response) in
+            if !cancellable.isCancelled {
             self.responseQueue.async {
-                onSuccess(response)
+                if !cancellable.isCancelled {
+                    onSuccess(response)
+                }
+            }
             }
         }
         
         let errorResponseQueue = { (error: PreviewError) in
+            if !cancellable.isCancelled {
             self.responseQueue.async {
+                if !cancellable.isCancelled {
                 onError(error)
+                }
+            }
             }
         }
         
         workQueue.async {
+            if cancellable.isCancelled {return}
+            
             if let url = self.extractURL(text: text) {
                 if let result = self.cache.slp_getCachedResponse(url: url.absoluteString) {
                     successResponseQueue(result)
                 } else {
-                    self.unshortenURL(url, completion: { unshortened in
+                    self.unshortenURL(url, cancellable: cancellable, completion: { unshortened in
                         if let result = self.cache.slp_getCachedResponse(url: unshortened.absoluteString) {
                             successResponseQueue(result)
                         } else {
                             
                             let canonicalUrl = self.extractCanonicalURL(unshortened)
                             
-                            self.extractInfo(unshortened, canonicalUrl: canonicalUrl, completion: { result in
+                            self.extractInfo(unshortened, cancellable: cancellable, canonicalUrl: canonicalUrl, completion: { result in
                                 
                                 var result = result
                                 

        task = session.dataTask(with: request, completionHandler: { data, response, error in
            if let _ = error {
                self.workQueue.async {
                    onError(PreviewError.cannotBeOpened(url.absoluteString))
                }
            } else {
                if let finalResult = response?.url {
                    if (finalResult.absoluteString == url.absoluteString) {
                        self.workQueue.async {
                            completion(url)
                        }
                    } else {
                        task!.cancel()
                        task = nil
                        self.unshortenURL(finalResult, completion: completion, onError: onError)
                    }
                } else {
                    self.workQueue.async {
                        completion(url)
                    }
                }
            }

            task.resume()
        } else {
            self.workQueue.async {
                if !cancellable.isCancelled {
                    onError(PreviewError.cannotBeOpened(url.absoluteString))
                }
            }
        }
    }
    
    // Extract HTML code and the information contained on it
    fileprivate func extractInfo(_ url: URL, cancellable: Cancellable, canonicalUrl: String?, completion: @escaping (Response) -> Void, onError: (PreviewError) -> ()) {
        if cancellable.isCancelled {return}
        
        if(url.absoluteString.isImage()) {
            var result = Response()
            
