ios 在flatmap中使用Swift Task进行异步/等待

pnwntuvh  于 2022-12-20  发布在  iOS
关注(0)|答案(1)|浏览(143)

我尝试在flatMap中接收async函数返回值,并将其 Package 在Task下以允许异步功能,但当我尝试访问Task值时出现此错误:
在不支持并发的函数中访问“async”属性
我该如何返回这个值呢?

  • Playground *
import UIKit

public func isEvenNumber(num:(Int)) async -> Result<Int, Error> {
    if num%2 == 0 {
        print("EVEN")
        return .success(1)
    }
    print("ODD")
    return .success(0)
}

func profileAsyncFunc() async -> Result<Bool, Error> {
    return await isEvenNumber(num: 3)
        .flatMap{ _ -> Result<Bool,Error> in
            
            Task {
                return await testAsyncFunc()
            }.value
         }
}

func testAsyncFunc() async -> Result<Bool, Error> {
    let basicTask = Task { () -> Result<Bool, Error> in
        .success(true)
    }
    return await basicTask.value
}

Task {
    await profileAsyncFunc()
}
sqxo8psd

sqxo8psd1#

几点意见:
1.快速并发大大简化了这一点,不需要flatMap

  1. isEvenNumber不是真正异步的,除非你await什么东西。添加async限定符并不使它异步。它只是意味着你可以在函数中添加一些异步代码,但只有当你await在函数中的东西。
    1.在Swift并发中,不再需要Result类型,它很快就变成了语法噪音。在async函数中,你可以简单地将return作为一个值,或者将throw作为一个错误。
    让我们假设isEvenNumber只是一个占位符,它代表了一些非常复杂的东西,您确实需要使它异步以避免阻塞当前参与者。此外,虽然您没有抛出错误,但让我们假设这是某个会抛出错误的方法的代理。
    如果所有的都是这样,你需要确保你用一个detached任务把它从当前的参与者那里得到,然后它将是异步的,就像你将await它的value一样,我随意定义isEven,如果值是负数,它将抛出一个错误。(显然,这不是抛出错误的合理理由,但出于说明目的,将其包括在内。)
    因此:
enum NumberError: Error {
    case negative
}

// This is not sufficiently computationally intensive to warrant making it run
// asynchronously, but let us assume that it was. You would do something like:

func isEven(_ num: Int) async throws -> Bool {
    if num < 0 { throw NumberError.negative }

    return await Task.detached {
        num.isMultiple(of: 2)
    }.value
}

func profileAsyncFunc() async throws -> Bool {
    try await isEven(3)
}

然后你可以这样做:

Task {
    let isEven = try await profileAsyncFunc()
    print(isEven)
}

你说:
我正在尝试接收flatMap内的async函数返回值...
在Swift并发中不需要flatMap,而在Combine中可能会用到。
如果你只是想采用async-await,你可以把它从你的代码中删除。如果你想通过引入flatMap来解决其他问题,请编辑问题,提供一个更完整的例子,并解释flatMap的基本原理。
照目前的情况看,这个例子过于简单化,以至于我们很难理解你真正想要解决的问题。

相关问题