文档手册

OnLoadData 同步,异步,分开加载数据

2024-07-09 16:19:39

设置回调函数代码:

// setup asset routes
	win.SetCallback(&sciter.CallbackHandler{
		OnLoadData: func(params *sciter.ScnLoadData) int {
			return customOnLoadData(params)
		},
	})


回调函数代码如下:

func customOnLoadData(params *sciter.ScnLoadData) int { 
    // 定义自定义的 OnLoadData 函数,参数是 Sciter 的 ScnLoadData 结构体指针

    rq := sciter.WrapRequest(params.RequestId()) 
    // 获取请求的接口,通过请求 ID 获取一个新的 Request 接口

    uri, _ := rq.Url() 
    // 获取请求的 URL
    
    rqType, _ := rq.RequestType() 
    // 获取请求类型,例如 GET 请求
    
    rqDataType, _ := rq.RequestedDataType() 
    // 获取请求的数据类型,例如 IMAGE 类型
    
    if strings.HasPrefix(uri, "sync://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { 
        // 如果 URI 以 "sync://" 开头,并且请求类型是 GET,请求的数据类型是 IMAGE
        
        path := uri[7:] 
        // 获取 "sync://" 之后的文件路径

        f, err := os.Open(path) 
        // 打开指定路径的文件

        if err != nil { 
            // 如果文件打开失败

            return sciter.LOAD_DISCARD 
            // 返回 LOAD_DISCARD 表示丢弃这个加载请求
        }

        data, err := ioutil.ReadAll(f) 
        // 读取文件中的所有数据

        if err != nil { 
            // 如果读取文件数据失败

            return sciter.LOAD_DISCARD 
            // 返回 LOAD_DISCARD 表示丢弃这个加载请求
        }

        rq.SetSucceeded(200, data) 
        // 请求成功,设置 HTTP 状态码 200 和读取的数据
    } else if strings.HasPrefix(uri, "async://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { 
        // 如果 URI 以 "async://" 开头,并且请求类型是 GET,请求的数据类型是 IMAGE
        
        go func() { 
            // 启动一个新的 goroutine 来异步加载数据

            path := uri[8:] 
            // 获取 "async://" 之后的文件路径

            f, err := os.Open(path) 
            // 打开指定路径的文件

            if err != nil { 
                // 如果文件打开失败

                rq.SetFailed(404, nil) 
                // 请求失败,设置 HTTP 状态码 404

                return 
                // 结束 goroutine
            }

            data, err := ioutil.ReadAll(f) 
            // 读取文件中的所有数据

            if err != nil { 
                // 如果读取文件数据失败

                rq.SetFailed(500, nil) 
                // 请求失败,设置 HTTP 状态码 500

                return 
                // 结束 goroutine
            }

            rq.SetSucceeded(200, data) 
            // 请求成功,设置 HTTP 状态码 200 和读取的数据
        }()

        return sciter.LOAD_DELAYED 
        // 返回 LOAD_DELAYED 表示数据会被异步加载
    } else if strings.HasPrefix(uri, "chunked://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { 
        // 如果 URI 以 "chunked://" 开头,并且请求类型是 GET,请求的数据类型是 IMAGE
        
        go func() { 
            // 启动一个新的 goroutine 来异步分块加载数据

            path := uri[10:] 
            // 获取 "chunked://" 之后的文件路径

            f, err := os.Open(path) 
            // 打开指定路径的文件

            if err != nil { 
                // 如果文件打开失败

                rq.SetFailed(404, nil) 
                // 请求失败,设置 HTTP 状态码 404

                return 
                // 结束 goroutine
            }

            buf := make([]byte, 1<<16) 
            // 创建一个 64KB 的缓冲区

            for { 
                // 循环读取文件数据

                n, err := f.Read(buf) 
                // 读取文件中的数据到缓冲区,返回读取的字节数

                rq.AppendDataChunk(buf[:n]) 
                // 将读取到的字节作为数据块追加到请求中

                if err == io.EOF { 
                    // 如果读取到文件末尾

                    rq.SetSucceeded(200, nil) 
                    // 请求成功,设置 HTTP 状态码 200

                    return 
                    // 结束 goroutine
                }
            }
        }()

        return sciter.LOAD_DELAYED 
        // 返回 LOAD_DELAYED 表示数据会被异步加载
    }

    return sciter.LOAD_OK 
    // 默认情况下,返回 LOAD_OK 表示数据已经成功加载
}


rq.RequestedDataType() 会有以下几种类型:


这段代码定义了一个枚举类型 SciterResourceType,用于表示不同类型的资源数据。下面是每个枚举常量的意义解释:

  1. RT_DATA_HTML: HTML 数据类型。表示请求的资源是 HTML 内容。

  2. RT_DATA_IMAGE: 图像数据类型。表示请求的资源是图像。

  3. RT_DATA_STYLE: 样式数据类型。表示请求的资源是样式表(CSS)。

  4. RT_DATA_CURSOR: 光标数据类型。表示请求的资源是光标图标。

  5. RT_DATA_SCRIPT: 脚本数据类型。表示请求的资源是脚本文件(如 JavaScript)。

  6. RT_DATA_RAW: 原始数据类型。表示请求的资源是原始数据,可能是未加工的二进制数据。

  7. RT_DATA_FONT: 字体数据类型。表示请求的资源是字体文件。

  8. RT_DATA_SOUND: 声音数据类型。表示请求的资源是声音文件(如 WAV 格式的音频)。

  9. RT_DATA_FORCE_DWORD: 强制将枚举值转换为 32 位无符号整数。在 C/C++ 中,这种做法有时用于强制枚举类型占用 32 位,但在 Go 中不需要。

这些枚举常量定义了不同种类的资源类型,允许程序根据请求的资源类型采取不同的处理方式,例如在加载数据时区分对待 HTML、图像、样式表等不同类型的资源。