ios - Swift4 - 如何应用异步函数数组的每个元素

标签 ios swift loops

**[编辑]**我有一个for循环,它应该从上到下逐一执行循环中的每一步,然后返回到顶部并再次重复这些步骤。但它并没有走到最后一步(这是一个函数),而是从中间回到第一步,获取所有参数,从上到中循环完所有步骤后,再转到最后一步,并多次运行该函数,但仅使用从上一步获取的最后一个参数。

我尝试将最后一步(函数)放在循环之外,但在循环中最后一个参数将覆盖前面的参数,并且函数将仅使用最后一个参数。

用于获取产品信息并将其添加到购物车的循环代码:

@IBAction func btnReorderTapped(_ sender: UIButton) {
    if !isReorderDisable {

        let orderItem = orderDetail.items

        func addToCart() {
            viewModel.addCartItem(success: {
                print("product added")
            }, failure: { (errorMessage) in
                self.showAlert(errorMessage)
                print("fail")
            })
        }

        var results: [CartItemData] = []

        for item in orderItem {

            let cartItem = CartItemData()

            cartItem.sku = item.sku
            cartItem.qty = item.qtyOrdered
            cartItem.name = item.name
            cartItem.price = item.price  

            results.append(cartItem)  
        }
        for i in 0...1 { // test two sets of value in results[i]
            viewModel.cartItem = results[i]
            addToCart()
        }
    }
}

函数“addCartItem”的代码:

/**
 Add new item to existing shopping cart
 */
func addCartItem(success: @escaping () -> Void, failure: @escaping (_ errorMessage : String) -> Void) {
    cart.cartItem = cartItem
    cart.cartItem?.quote_id = "\(CartInfo.getCartID() ?? 0)"

    if ReachabilityUtil.shareInstance.isOnline() {
        beforeApiCall?()

        // IF CART NOT CARTE, CRATE THE CART AND RETRY CART ITEM ADD
        createCartData(success: { (_) in
            self.cart.cartItem?.quote_id = "\(CartInfo.getCartID() ?? 0)"
            // CHECK CART LIMIT BEFORE ADDING NEW ITEM INTO CART
            self.checkCartLimit(success: { (checkLimit) in
                if let limitErrors = checkLimit.limit_errors {
                    for limitError in limitErrors {
                        switch limitError.typeLimit {
                        case .cartItemAndTotalLimitExcced, .cartItemLimitExceed, .cartTotalLimitExceed:
                            failure(limitError.message)
                            return
                        default:
                            break
                        }
                    }
                }

                // ADD ITEM TO CART
                CartApiManager.sharedInstance.doAddCartItem(data: self.cart.toJSON(), completed: { (apiResponseHandler, error) in
                    self.afterApiCall?()

                // print("cartData-", self.cart)

                    if apiResponseHandler.isSuccess() {
                        // UPDATE CART DATA IN LOCAL DB
                        self.getCartData(success: { (_) in

                        }, failure: { (errorMessage) in
                            print("\(errorMessage)")
                        })

                        // UPDATE CART SUMMARY DATA IN LOCAL DB
                        self.getCartSummary(success: {

                        }, failure: { (errorMessage) in
                            print("\(errorMessage)")
                        })

                        success()
                    } else {
                        failure(apiResponseHandler.errorMessage())
                    }
                })
            }, failure: { (errorMessage) in
                self.cart.cartItem?.quote_id = "\(CartInfo.getCartID() ?? 0)"

                // CHECK LIMIT MAY BE FAILURE ON FIRST STAGE, SO WE ALLOWED TO ADD ITEM INTO CART
                CartApiManager.sharedInstance.doAddCartItem(data: self.cart.toJSON(), completed: { (apiResponseHandler, error) in
                    self.afterApiCall?()

                    if apiResponseHandler.isSuccess() {
                        // UPDATE CART DATA IN LOCAL DB
                        self.getCartData(success: { (_) in

                        }, failure: { (errorMessage) in
                            print("\(errorMessage)")
                        })

                        // UPDATE CART SUMMARY DATA IN LOCAL DB
                        self.getCartSummary(success: {

                        }, failure: { (errorMessage) in
                            print("\(errorMessage)")
                        })

                        success()
                    } else {
                        failure(apiResponseHandler.errorMessage())
                    }
                })
                return
            })
        }, failure: { (errorMessage) in
            failure(errorMessage)
        })
    }
}

预期的打印消息应该是:

sku- xxxxxx
final- CartItemData {
    sku = xxxxxx;
    qty = 1;
    name = nnnnnn;
    price = 100;
    product_type = ;
    quote_id = ;
}
cartData- CartItemData {
    sku = xxxxxx;
    qty = 1;
    name = nnnnnn;
    price = 100;
    product_type = ;
    quote_id = ;
}
product added
sku- yyyyyy
final- CartItemData {
    sku = yyyyyy;
    qty = 1;
    name = mmmmmm;
    price = 200;
    product_type = ;
    quote_id = ;
}
cartData- CartItemData {
    sku = yyyyyy;
    qty = 1;
    name = mmmmmm;
    price = 200;
    product_type = ;
    quote_id = ;
}
product added

应该有两个商品添加到购物车中。但是,

实际打印消息是:

sku- xxxxxx
final- CartItemData {
    sku = xxxxxx;
    qty = 1;
    name = nnnnnn;
    price = 100;
    product_type = ;
    quote_id = ;
}
sku- yyyyyy
final- CartItemData {
    sku = yyyyyy;
    qty = 1;
    name = mmmmmm;
    price = 200;
    product_type = ;
    quote_id = ;
}
cartData- CartItemData {
    sku = yyyyyy;
    qty = 1;
    name = mmmmmm;
    price = 200;
    product_type = ;
    quote_id = ;
}
product added

所以最终添加的项目只是第二个项目。

请任何人都可以告诉我如何将异步函数“addCartItem”应用于数组“results”中的每个元素?非常感谢!

最佳答案

  • 由于 viewModel.addCartItem 有一个 API 调用,该调用在该 API 调用中使用 cartItem 模型,因此解决方案将通过传递 cartItem code> 作为单独的参数添加到 addCartItem 函数中。
  • 这是因为 API 调用是异步发生的,因此他们都会看到您分配给 viewModel 的最后一个 cartItem。

如果您将调用 addCardItem 函数的方式更改为:

,它应该可以正常工作:
func addCartItem(_ cartItem: CartItemData, success: @escaping () -> Void, failure: @escaping (_ errorMessage : String) -> Void) {
   // here user cartItem instead of self.cartItem
}

您应该替换以下调用:

viewModel.addCartItem(success: {
            print("product added")
            }, failure: { (errorMessage) in
                self.showAlert(errorMessage)
            print("fail")
            })

作者:

viewModel.addCartItem(cartItem, success: {
            print("product added")
            }, failure: { (errorMessage) in
                self.showAlert(errorMessage)
            print("fail")
            })

关于ios - Swift4 - 如何应用异步函数数组的每个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56421467/

相关文章:

ios - 使用自动布局使 CustomView 适合 SuperView

android - 是否可以在 React.js Native 中使用 eval() 来定义应用程序中的新体验?

c - 如果满足条件,则递减数组并打印值

iOS - 我可以自定义由 Apple 托管的应用内购买内容吗?

ios - 我怎么知道还没有提供接收推送通知?

swift - 错误 : Cannot convert value of type

ios - 我正在创建一个 Collection View ,其中所有单元格的高度都是随机的。如何使单元格之间的垂直间距为0?

c++ - 如何在运行时实现 base 2 循环展开以进行优化

r - 如何避免 R 中的循环?

iphone - 如何将 ManagedObjectContext 传递给 TabBarViewController