需求:MutationObserver 的回调内部需要 await 读取环境变量,且原子化的运行(前一次变动的回调没执行完前,不会有新的回调同时运行)
只是简单地在回调里面用 await ,声明前加上 async ,显然不管用。于是尝试了下面的写法:回调里先把观察器断掉,等处理完其他事,返回前再连上。虽然写法很丑陋,且会丢掉一些变动没处理,但不影响使用场景:
let ManualHider = function(rules) {
this.run = function() {
this.list_observer = new MutationObserver(this.callback);
this.list_observer.observe(document.querySelector(this.matching_unique_rule.root), {
childList: true
});
}
this.callback = async function() {
this.list_observer.disconnect(); // 报错的行
await new Promise(r => setTimeout(r, 3000)); // do sth asynchronously
this.list_observer.observe(document.querySelector(this.matching_unique_rule.root), {
childList: true
});
}
};
new ManualHider(rules).run();
但是当第二次触发时,this 会变成 undefined ,提示 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'disconnect')。
这是为什么呀?另外若这种写法实在不行,还有什么简单方法(太专业的搞不来…)能实现需求吗?谢谢
(楼主文科生,偶尔代码仅自用,若说的不对,请大佬对业余者宽容谅解)
1
xy90321 2023-02-02 23:26:09 +08:00 via iPhone 1
另外搞一个队列,observer 的回调只负责往队列里面塞消息,另外开个处理去顺次消费队列里面的消息就可以了
|
4
ie88 2023-02-02 23:54:08 +08:00 2
@axo 我从某本书摘几句话给你,有空看看 ES6/7/Next
- Inside a `normal function`, `this` is a reference to the context object that the function is operating on - Inside an `arrow function`, `this` refrences the context in which the arrow function expression is defined. - when used inside global `normal functions`, `this` is equal to `window` in nonstrict mode and `undefined` in strict mode |
5
lisongeee 2023-02-03 00:02:49 +08:00 1
```js
let ManualHider = function(rules) { this.run = function() { this.list_observer = new MutationObserver(this.callback); this.list_observer.observe(document.querySelector(this.matching_unique_rule.root), { childList: true }); } this.task = Promise.resolve() this.callback = ()=> { this.task = this.task.finally(async()=>{ await new Promise(r => setTimeout(r, 3000)); // do sth asynchronously }) } }; new ManualHider(rules).run(); ``` |
6
lisongeee 2023-02-03 00:06:55 +08:00 1
确实还要把 this 。run=function(){ 换成 this 。run=()=>{
|
7
lisongeee 2023-02-03 00:07:57 +08:00 1
我使用 。而不是 . 是因为 V2EX 把上一条评论认为包含外链不让发送
|
9
autoxbc 2023-02-03 00:47:04 +08:00
只是为了让一串异步函数顺序执行,没必要把观察者接来接去,只要把 promise 接起来就够了,也就两行代码
let promise = Promise.resolve(); const run = asyncFunction => promise = promise.then( () => asyncFunction() ); const getAsyncFunction = name => async () => { console.log(`${ name } begin`); await new Promise( resolve => setTimeout( resolve , 3000 ) ); console.log(`${ name } end`); }; run( getAsyncFunction('f1') ); run( getAsyncFunction('f2') ); run( getAsyncFunction('f3') ); |
10
justdoit123 2023-02-03 10:17:53 +08:00
歪个楼,话说各位 js 们写业务代码还会用到 call/bind/apply 吗?我个人观点:js 里的 context bind 跟 C 语言里的 goto 一样,需要用到的场景已经很少了。
|
11
angrylid 2023-02-03 10:53:49 +08:00
习惯上会这样写吧:
function ManualHider(rules) { this.rules = rules; } ManualHider.prototype.run = function() { this.list_observer = new MutationObserver(this.callback); this.list_observer.observe(document.querySelector(this.matching_unique_rule.root), { childList: true }); } ManualHider.prototype.callback = async function() { this.list_observer.disconnect(); // 报错的行 await new Promise(r => setTimeout(r, 3000)); // do sth asynchronously this.list_observer.observe(document.querySelector(this.matching_unique_rule.root), { childList: true }); } new ManualHider({}).run(); |
13
justdoit123 2023-02-06 10:04:08 +08:00
@wdssmq 是哦! 不过也确实少用了。
|