const a = (): Promise<void> => {
return new Promise((resolve) => {
const callback = (mutations: MutationRecord[]) => {
// 监听按钮的某个属性变化,此处退出函数
resolve();
};
const observer = new MutationObserver(callback);
observer.observe(buttonEl, {
attributes: true,
});
// 调用一个Promise函数,成功后触发按钮的点击事件,然后监听按钮的属性变化
p().then(() => {
buttonEl.click();
});
});
};
const b = async (): Promise<void> => {
const callback = (mutations: MutationRecord[]) => {
// 监听按钮的某个属性变化,怎么在此处退出函数?
};
const observer = new MutationObserver(callback);
observer.observe(buttonEl, {
attributes: true,
});
// 调用一个Promise函数,成功后触发按钮的点击事件,然后监听按钮的属性变化
await p();
buttonEl.click();
};
如上述示例代码,a
是常规的Promise写法,现在想要改成b
那样的async写法,请问该怎么办?
想要这么改的原因是函数内部的逻辑逐渐复杂,会调用多个Promise函数,常规写法会陷入层层嵌套的窘境,不利于维护。
只把observer相关逻辑用Promise包起来?
const b = async (): Promise<void> => {
const promise = new Promise(resolve => {
const callback = (mutations: MutationRecord[]) => {
// 监听按钮的某个属性变化,怎么在此处退出函数?
resolve();
};
const observer = new MutationObserver(callback);
observer.observe(buttonEl, {
attributes: true,
});
})
// 调用一个Promise函数,成功后触发按钮的点击事件,然后监听按钮的属性变化
await p();
buttonEl.click();
return promise;
};
你的需求可能需要最新的Promise.withResolvers()接口,目前还是Stage-4
阶段。
const b = async (): Promise<void> => {
const { promise, resolve } = Promise.withResolvers<void>()
const callback = (mutations: MutationRecord[]) => {
resolve();
};
const observer = new MutationObserver(callback);
observer.observe(buttonEl, {
attributes: true,
});
// 调用一个Promise函数,成功后触发按钮的点击事件,然后监听按钮的属性变化
await p();
buttonEl.click();
// 下面这句也可以用 return promise,取决于你的后续逻辑
await promise
};
这个功能才出没多久,考虑兼容旧的浏览器,你可能需要更新core-js
。
另外,你用了TS,如果需要通过类型检查,可能还要把TS更新到5.4或以上,然后在tsconfig.json
里确保配置lib
有ESNext
这一项。
在b
函数中,你无法直接在MutationObserver
的回调函数callback
中直接“退出”async
函数,因为async
函数执行的是基于Promise的异步流程,而MutationObserver
的回调是一个事件监听器,它并不直接参与Promise的解析或拒绝。
然而,你可以通过其他方式来实现你的目标,比如使用一个外部标志来控制是否继续观察或者解除观察。以下是一个基于你给出的代码示例的修改版本:
const b = async (): Promise<void> => {
let isObserved = true; // 外部标志
const callback = (mutations: MutationRecord[]) => {
// 监听按钮的某个属性变化,当满足条件时停止观察
if (/* 判断条件 */) {
if (isObserved) {
isObserved = false;
observer.disconnect(); // 停止观察
}
// 注意:这里不能直接return退出async函数,但可以通过其他方式(如Promise的resolve)通知外部
}
};
const observer = new MutationObserver(callback);
observer.observe(buttonEl, {
attributes: true,
});
// 调用一个Promise函数,成功后触发按钮的点击事件,然后监听按钮的属性变化
await p();
buttonEl.click();
// 如果需要等待属性变化后再继续执行后续代码,则需要额外处理
// 可以通过另一个Promise来等待,比如使用Promise的race来监听某个信号
// 注意:下面的代码仅用于演示,实际中你可能需要更复杂的逻辑来管理这个Promise
// let waitForMutation = new Promise<void>((resolve) => {
// // 这里添加逻辑来在某些条件下resolve这个Promise
// });
// await Promise.race([waitForMutation, someOtherTimeoutOrSignal]);
// 由于上面的waitForMutation并没有实际实现,所以这里直接返回
return;
};
请注意,在上面的代码中,我添加了一个isObserved
标志来控制是否继续观察。当满足某个条件时,我们设置isObserved
为false
并调用observer.disconnect()
来停止观察。然而,这并不意味着async
函数b
会“退出”——它只是停止了对DOM元素的观察。
如果你想要在属性变化后继续执行async
函数中的后续代码,你可能需要创建一个新的Promise(如上面的waitForMutation
)并在某个条件下解析它。然后,你可以使用await
来等待这个Promise,从而暂停async
函数的执行直到属性变化发生。但是,由于MutationObserver
的回调是异步触发的,你不能直接在回调中解析这个Promise,你需要通过其他方式(如信号量、事件或其他同步原语)来协调。
问题内容: 例如我想在10.00.00.00 am调用js函数,我该怎么办? 我希望从此代码在00.30开始打开google,然后每隔1分钟就会再次打开它?该代码有什么问题? 问题答案: 您将需要setTimeout来设置计时器,并需要Date来计算计时器需要多长时间才能触发。
如果我使用某种硬编码条件,例如,我会得到Typescript错误消息: 当然,我可以在这里定义来禁用任何TypeScript检查,代码将编译并运行,但我的目标是能够仅通过签名来区分函数(而不依赖于其他约定,如名称或其他标志)。
问题内容: 我试图在jQuery中使用getJSON函数导入一些数据并触发回调函数。回调函数未运行。但是,如果我使用get函数尝试相同的操作,则效果很好。奇怪的是,即使我将“ json”作为类型传递,它也可以与get函数一起使用。为什么会这样呢?我在Firefox 3和IE 7中测试了以下文件: 只要我访问的URL在同一个域中,这似乎都会发生。我尝试传递一些数据,但这没有什么不同。 当然,可以像在
问题内容: 我有一段使用解释器执行的JavaScript代码。 如何测量这些数据库插入操作所花费的时间?我可以计算这段代码前后的日期值之差,但是由于代码的异步特性,这将是不正确的。 问题答案: 使用Node.js 和:
问题内容: 传统上,要在页面加载后调用JavaScript函数,您需要在包含一些JavaScript的正文中添加一个属性(通常只调用一个函数) 页面加载后,我想运行一些JavaScript代码以使用服务器中的数据动态填充页面的某些部分。因为我使用的是JSP片段,所以我无法使用该属性,而JSP片段没有可以添加属性的元素。 还有其他方法可以在加载时调用JavaScript函数吗?我宁愿不使用jQuer
我正在使用jQuery,我有一个函数作为事件回调,所以在这个函数中,“this”代表捕获事件的对象。然而,有一个实例,我想从另一个函数显式调用函数——在这种情况下,我如何在函数中设置“this”等于什么? 例如: