简体   繁体   English

如何从Kotlin中的协程scope返回一个变量

[英]How to return a variable from inside coroutine scope in Kotlin

I have a jsoup function inside of a coroutine that scrapes information from a website and then gets a list of maps of all of the information it scraped.我在协程中有一个jsoup function,它从网站上抓取信息,然后获取它抓取的所有信息的地图列表。 However, whenever I try to return the list, this is returned instead:但是,每当我尝试返回列表时,都会返回:

"Function0<java.util.List<java.util.Map<java.lang.String, ? extends java.lang.String>>>"

Here is the code for the function:这是 function 的代码:

suspend fun popularHome(
    pg: String
): Any = withContext(Dispatchers.IO) {
    val table = mutableListOf<Map<String, String>>()

    val doc: Document = Jsoup
        .connect("https://www.novelupdates.com/novelslisting/?sort=2&order=1&status=1&pg=$pg")
        .userAgent("Mozilla/5.0")
        .referrer("http://www.google.com")
        .ignoreContentType(true)
        .get()

    val imageLists = doc.getElementsByClass("search_img_nu")
    val lists = doc.getElementsByClass("search_main_box_nu")

    for ((list, imageList) in lists.zip(imageLists)) {
        val searches: Elements = list.getElementsByClass("search_title")
        val imageSearches: Elements = imageList.getElementsByTag("img")

        for ((search, imageSearch) in searches.zip(imageSearches)) {
            val titles = search.getElementsByTag("a")
            val ranks = search.getElementsByClass("genre_rank")

            for ((title, rank) in titles.zip(ranks)) {
                val link: String = title.attr("href") // Book Link
                val titleName: String = title.text() // Book Title
                val imageLink: String = imageSearch.attr("src") // Book Image Link
                val rankName: String =
                    rank.text().replace("#", "") // Book Popularity Rank

                table.add(
                    mutableMapOf<String, String>(
                        "rank" to rankName,
                        "title" to titleName,
                        "link" to link,
                        "image" to imageLink
                    )
                )

            }
        }
    }
    Log.i("tag", table.toString())

    return@withContext { table }
}

Here is the code for Main Activity :这是Main Activity的代码:

package com.example.sushi

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.example.sushi.service.repos.novelupdates.com.NovelUpdatesScraper
import com.example.sushi.ui.styling.SushiTheme
import kotlinx.coroutines.*


class MainActivity : ComponentActivity() {
    val scrape = NovelUpdatesScraper()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SushiTheme {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(text = "Hey")
                }
            }
        }
        lifecycleScope.launch {
            Log.i("tag", scrape.popularHome("1").toString())
        }
    }
}

No matter where I put the return I can't get it to give me anything but an empty list.无论我把退货放在哪里,除了一个空列表,我什么也得不到。 Yet when I log the list it gives me all of the information that was scraped.然而,当我记录列表时,它会为我提供所有被抓取的信息。

I already tried this solution: How to return a value inside a coroutine scope kotlin, android and this solution: How to return value from coroutine scope我已经尝试过这个解决方案: How to return a value inside a coroutine scope kotlin, android这个解决方案: How to return value from coroutine scope

In the code, when you call return@withContext { table } mean it will return () -> List instead of the List instance.在代码中,当您调用return@withContext { table }时,意味着它将返回() -> List而不是List实例。

Just call return@withContext table and it should be fixed.只需调用return@withContext table ,它就应该被修复。

Btw, I believe you should not set the function return type to Any .顺便说一句,我相信你不应该将 function 返回类型设置为Any
If you know exactly what you gonna do and you expect this function will return a List then the return type should be List<Map<String, String>> , there is no reason to set it as Any .如果你确切地知道你要做什么并且你期望这个 function 将返回一个 List 那么返回类型应该是List<Map<String, String>> ,没有理由将它设置为Any

The immediate benefits that can be seen is if you set the return type as List<Map<String, String>> and call return@withContext { table } , the Android Studio IDE will show you what went wrong.可以看到的直接好处是,如果您将返回类型设置为List<Map<String, String>>并调用return@withContext { table } ,Android Studio IDE 将告诉您哪里出了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM