我有这个脚本加载承诺,我需要转换为observable。我需要在ngOnDestroy上取消这个承诺,在googling之后我发现这是不可能的,因此我想把它转换成一个可观察的。
this.visualizePromise = new Promise((resolve, reject) => {
script.setAttribute('src', `${process.env.JASPER_SERVER}/client/visualize.js`);
script.onload = () => {
console.log('script loaded')
window['visualize']({
auth: {
name: process.env.JASPER_NAME,
password: process.env.JASPER_PASSWORD,
organization: process.env.JASPER_ORGANIZATION
}
}, resolve, reject);
};
script.onerror = () => {
this.errMsg = true;
this.error = 'Failed to load visualize';
this.showLoader = false;
};
document
.body
.appendChild(script);
});
this
.visualizePromise
.then(visualize => {
if (typeof visualize.report === 'function') {
return visualize;
}
throw 'Failed to load visualize';
})
.then(visualize => {
this.visualize = visualize;
this.showLoader = false;
// do stuff here
})
.catch(() => {
this.errMsg = true;
this.error = 'Failed to load visualize';
this.showLoader = false;
});
我想把它改成这样的东西,
import { Observable } from "rxjs/Observable"
// create observable
const simpleObservable = new Observable((observer) => {
// observable execution
observer.next("bla bla bla")
observer.complete()
})
// subscribe to the observable
simpleObservable.subscribe()
// dispose the observable
simpleObservable.unsubscribe()
答案 0 :(得分:1)
在评论中作出澄清后,您可以执行以下操作。我保留了你的所有逻辑,包括script.onerror
拒绝(或解决)承诺的(可疑的)决定。因此,如果脚本无法加载,则此observable将永远不会完成。
const visualize$ = Observable.create(observer => {
const resolve = val => {
observer.next(val);
observer.complete();
};
script.setAttribute('src', `${process.env.JASPER_SERVER}/client/visualize.js`);
script.onload = () => window['visualize']({
auth: {
name: process.env.JASPER_NAME,
password: process.env.JASPER_PASSWORD,
organization: process.env.JASPER_ORGANIZATION
}
}, resolve, observer.error);
script.onerror = () => {
this.errMsg = true;
this.error = 'Failed to load visualize';
this.showLoader = false;
};
document.body.appendChild(script);
});
旁注,你提到了
// dispose the observable
simpleObservable.unsubscribe()
这将永远不会起作用,因为取消订阅发生在订阅上,而不是发生在可观察的上。
答案 1 :(得分:0)
我做了一个实例,请查看convert-script-load-promise-to-observable。请记住,如果您想将auth标头添加到某个请求中,则应该在Interceptor中执行此操作。
<强> your.component.ts 强>
ngOnInit() {
let script, process;
this.mySubcription = this.service.fromPromiseToObservable(script, process)
.do(visualize => {
this.visualize = visualize;
this.showLoader = false;
// do stuff here
}).subscribe(visualize => {
if (typeof visualize.report === 'function') {
return visualize;
}
return Observable.throw('Failed to load visualize');
}, () => {
this.service.errMsg = true;
this.service.error = 'Failed to load visualize';
this.service.showLoader = false;
});
}
ngOnDestroy() {
this.mySubcription.unsubscribe();
}
<强> your.service.ts 强>
fromPromiseToObservable(script, process): Observable<any> {
this.visualizePromise = new Promise((resolve, reject) => {
script.setAttribute('src', `${process.env.JASPER_SERVER}/client/visualize.js`);
script.onload = () => {
console.log('script loaded')
window['visualize']({
auth: {
name: process.env.JASPER_NAME,
password: process.env.JASPER_PASSWORD,
organization: process.env.JASPER_ORGANIZATION
}
}, resolve, reject);
};
script.onerror = () => {
this.errMsg = true;
this.error = 'Failed to load visualize';
this.showLoader = false;
};
document
.body
.appendChild(script);
});
return Observable.fromPromise(this.visualizePromise);
}