ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.
function* myGenerator() {
const callback = yield;
let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
console.log("response is:", response);
// examples of other things you can do
yield setTimeout(callback, 1000);
console.log("it delayed for 1000ms");
while (response.statusText === "error") {
[response] = yield* anotherGenerator();
}
}
Для запуска вышеуказанного кода вы делаете это:
const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function
Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.
Обратный вызов ...args
завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :
const [err, data] = yield fs.readFile(filePath, "utf-8", callback);
Это было ответино довольно давно, но есть смесь отсутствующей и не быстрой информации, поэтому вот моя версия в надежде, что она поможет кому-то, кому нужен более полный пример обработчика завершения:
avc.completionWithItemsHandler = {[weak self](activityTypeChosen, completed:Bool, returnedItems:[AnyObject]?, error:NSError?) -> Void in
// ReturnedItems is an array of modified NSExtensionItem, or nil of nothing modified
// if (activityType == nil) User dismissed the view controller without making a selection.
// Dismiss the view controller we presented
// (assume a reference to it was stored in self.activityVC)
self?.activityVC?.dismissViewControllerAnimated(true, completion: {
if activityTypeChosen == nil {
NSLog("User canceled without choosing anything")
}
else if completed {
NSLog(")User chose an activity and iOS sent it to that other app/service/whatever OK")
}
else {
NSLog("There was an error: \(error)")
}
})
}
Обратите внимание на строку, в которой он отклоняет контроллер вида. Документы для UIActivityViewController очень четко говорят о том, что ваше приложение несет ответственность за то, что они отображают VC и , отклоняя его.
Тип завершенностиWithItemsHandler:
typealias UIActivityViewControllerCompletionWithItemsHandler = (String?, Bool, [AnyObject]?, NSError?) -> Void
Примечание: предыдущий блок кода не должен использоваться в вашем проекте, он просто показывает необходимый тип закрытия ( docs ) ,
Таким образом, это параметры, которые передаются в обработчик завершения для вас, как вы это сделаете, поэтому обработчик завершения будет выглядеть следующим образом:
avc.completionWithItemsHandler = { activity, success, items, error in
}
ПРИМЕЧАНИЕ. Поскольку я не читал часть вопроса «SWIFT», я ответил на вопрос в Obj-C. Мой плохой, К OP: Прошу прощения
Вот более полный ответ, который можно скомпилировать. Я использовал: dispatch_async
для того, чтобы сделать предупреждение, чтобы вы могли видеть, что «activityType» закончилось.
avc.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertViewQuick(@"Activity Status", activityType, @"OK");
});
if (completed)
{
NSLog(@"The Activity: %@ was completed", activityType);
}
else
{
NSLog(@"The Activity: %@ was NOT completed", activityType);
}
};
Как этот ответ говорит, что для Swift 3 и 4 и iOS 10 и 11 используйте его следующим образом:
activityVC.completionWithItemsHandler = {(activityType: UIActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
}
present(activityVC, animated: true, completion: nil)