自己实现的一个Script Callback

自己实现的一个Script Callback

昨天网上一位朋友推荐我看了一篇文章《Remote Scripting in .NET》,这篇文章的作者利用了Microsoft Remote Scripting技术,在服务器端进行了一些封装,方便了在ASP.NET中的页面上调用直接调用服务器端方法。

说起来我以前对Microsoft Remote Scripting还是挺陌生的,MRS的原理是利用了内置的一个Java Applet,通过一些高层的封装,使页面上使用Script能够直接调用服务器上公开的方法。感兴趣的朋友可以看看MSDN上的文档,用起来还算是方便,特别是配合前面那篇文章作者做的那个封装的.NET组件

不过我个人对Applet并不是很感冒,特别是在我家里的那台没有安装JRE的WinXP SP2RC2的机器上更是根本没法用...

其实我最喜欢的还是ASP.NET 2.0中的Script Callback那样的实现方式,简单、明了,于是想到,既然它也是底下使用XMLHTTP来实现的,那不如我自己在ASP.NET 1.1下面也照样用XMLHTTP实现一个好了。花费了一阵功夫,大功告成。大部分都是仿造的ASP.NET 2.0中的实现方式,但是部分地方还是不能做到完全一样,因为对于实现ICallbackEventHandler接口的控件的处理,我没法直接写到Page类或更里面的地方,所以需要在页面里面创建一个ScriptCallbackManager的控件。

服务器端的进行步骤:
1、让页面上的某个控件实现ICallbackEventHandler接口,我个人喜欢就让Page类直接实现;
2、在实现了ICallbackEventHandler接口的控件上实
现RaiseCallbackEvent方法,来处理客户端的请求;
3、在页面中加入一个ScriptCallbackManager控件,在构造函数中指明实现了ICallbackEventHandler接口的控件,和调用完成后执行客户端的Script函数名。

public class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
{
    private void Page_Load(object sender, System.EventArgs e)
    {
        this.Controls.Add(new ScriptCallbackManager(this, "handleResultFromServer"));
    }

    public String RaiseCallbackEvent(String eventArgument)
    {
        return "You sent " + eventArgument + " !";
    }


页面上的进行步骤:
1、在需要调用服务器方法的地方直接调用内置的scriptCallback()函数,第一个参数指定了要传递到服务器端的变量,第二个参数指定了此次请求的上下文;
2、编写一个在完成调用之后自动执行的函数,这个函数的名称需要和服务器端ScriptCallbackManager控件的构造函数中指定的函数名称相同。

function callBack()
{
    var param = document.all.txtRequest.value;
    var context = "";
   
    scriptCallback(param, context);
}

function handleResultFromServer(result, context)
{
    alert(result);
}


在callBack()方法中调用了系统内置的一个Script函数scriptCallBack(),这个函数会自动调用服务器方法,并将第一个参数的值传给服务器端的RaiseCallbackEvent()方法的参数。handleResultFromServer是在调用完成后自动执行的函数。

感兴趣的朋友可以在这里下载到这个Script Callback实现的项目源码。

发表于 Monday, August 02, 2004 11:39 PM

 

转自:Kaneboy's CodingLife Blog

你提到“封装一个带有 callback 的函数”,我们可以从多个角度来理解这个需求。在前端开发中,**带回调的函数**通常用于: - 处理异步操作(如 API 请求、定时任务) - 与旧式 API 兼容(非 Promise 风格) - 提供成功/失败后的自定义逻辑执行入口 下面我将为你 **完整封装一个通用且实用的带 callback 函数**,并支持: - 成功回调 `onSuccess` - 失败回调 `onError` - 支持 Promise 和传统 callback 两种调用方式(兼容性好) --- ### ✅ 示例:封装一个「删除用户」操作的函数,带 callback ```js // utils/deleteUser.js /** * 删除用户函数 - 支持 callback 和 Promise 两种方式 * @param {string} userId - 用户 ID * @param {Object} callbacks - 回调函数对象 * @param {Function} callbacks.onSuccess - 成功回调 * @param {Function} callbacks.onError - 错误回调 * @returns {Promise} */ export const deleteUser = (userId, { onSuccess, onError } = {}) => { // 返回 Promise,以便支持 await / then return new Promise((resolve, reject) => { // 模拟异步请求(比如调用后端 API) setTimeout(() => { try { if (!userId) { const error = new Error('用户 ID 不能为空') if (typeof onError === 'function') { onError(error) } reject(error) return } // 模拟删除成功 const result = { success: true, data: { deletedId: userId, timestamp: Date.now() } } if (typeof onSuccess === 'function') { onSuccess(result.data) } resolve(result.data) } catch (err) { if (typeof onError === 'function') { onError(err) } reject(err) } }, 800) }) } ``` --- ### 💡 使用方式一:使用 Callback(传统方式) ```js import { deleteUser } from '@/utils/deleteUser' deleteUser('123', { onSuccess: (data) => { console.log('删除成功:', data) alert('删除成功!') }, onError: (error) => { console.error('删除失败:', error.message) alert('删除失败:' + error.message) } }) ``` --- ### 💡 使用方式二:使用 Promise(现代方式) ```js import { deleteUser } from '@/utils/deleteUser' const handleDelete = async () => { try { const result = await deleteUser('123') console.log('删除成功:', result) } catch (error) { console.error('删除失败:', error.message) } } handleDelete() ``` --- ### 💡 使用方式三:同时使用两者(兼容混合场景) ```js deleteUser('456', { onSuccess: (data) => { console.log('[Callback] 已记录日志:', data) }, onError: (err) => { console.warn('[Callback] 捕获错误:', err.message) } }).then(() => { console.log('[Promise] 可继续链式处理') }).catch(() => {}) ``` > ✅ 这种设计既保持了向后兼容性,又支持现代化语法。 --- ### 🧩 更进一步:封装成 Vue 中可复用的 Hook ```js // composables/useDelete.js import { ElMessageBox, ElMessage } from 'element-plus' import { deleteUser } from '@/utils/deleteUser' export const useDeleteUser = () => { return (userId, options = {}) => { const { title = '删除确认', message = '此操作不可撤销,确定要删除吗?', type = 'error', onSuccess, onError, } = options // 弹出确认框 ElMessageBox.confirm(message, title, { confirmButtonText: '确定', cancelButtonText: '取消', type, closeOnClickModal: false, closeOnPressEscape: false, }) .then(() => { // 用户确认后执行删除 deleteUser(userId, { onSuccess, onError }).catch((err) => { if (!onError) { ElMessage.error(err.message || '删除失败') } }) }) .catch(() => { ElMessage.info('已取消删除') }) } } ``` #### 在组件中使用: ```vue <script setup> import { useDeleteUser } from '@/composables/useDeleteUser' const deleteUserAction = useDeleteUser() const handleDelete = () => { deleteUserAction('789', { onSuccess: (data) => { ElMessage.success(`删除成功:${data.deletedId}`) }, onError: (err) => { ElMessage.error(err.message) } }) } </script> <template> <el-button type="danger" @click="handleDelete">删除用户</el-button> </template> ``` --- ### ✅ 总结:为什么这样封装? | 特性 | 实现 | |------|------| | ✅ 支持 callback | 接收 `onSuccess` 和 `onError` 参数 | | ✅ 支持 Promise | 返回 Promise 对象 | | ✅ 异常安全 | 使用 try/catch 包裹异步逻辑 | | ✅ 易于测试 | 逻辑独立,无副作用 | | ✅ 可扩展性强 | 可加入 loading、重试机制等 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值