![](/img/trans.png)
[英]Is it possible to set the value of `this` inside a promise executor function?
[英]Listen for when promise resolves inside executor function
return new Promise(function(resolve, reject {
const to = setTimeout(function(){
});
});
想像一下,我想確保從執行程序函數內部清理資源。
我想做這樣的事情:
return new Promise(function(resolve, reject {
const to = setTimeout(function(){
});
this.finally(function(){
clearTimeout(to);
});
});
但是this
並不是一個承諾執行功能的使用。 有什么辦法可以清除諾言執行器中的異步資源?
我猜您可以在呼叫解決/拒絕之前清理它們,但是在某些情況下,這樣做比較困難。
不知道觸發后是否需要清除超時,但是您可以嘗試以下操作:
var someTest = () => {
var t;
var p = new Promise(
(resole)=>{
t = setTimeout(resole,2000)
}
);
p.finally(
()=>console.log(t,clearTimeout(t))
)
return p;
}
someTest();
或者,您可以嘗試以下操作:
var someTest = () =>
new Promise(
(resole)=>{
t = setTimeout(resole,2000)
}
).then(
result=>{
//clean up
return result
},
error=>{
//clean up
return Promise.reject(error)
}
);
從諾言執行者內部,您無法訪問諾言。 尚未分配給您的代碼可以訪問的任何內容。
因此,您有兩個選擇。
p.finally()
訪問返回的promise。 然后,您還必須在執行程序之外跟蹤資源(這可能很不方便)。 resolve()
和reject()
回調,以進行清理,然后調用實際的resolve()
或reject()
。 p.finally()
執行程序外部調用resolve / reject,從而使您可以訪問p.finally()
以及resolve()
和reject()
都在同一范圍內(這實際上是原始挑戰)。 這是選項2的示例:
return new Promise(function(rv, rj) {
// have to try/catch here because an execption will automatically reject
// without us having seen it
try {
// declare wrappers that should be called by code in this executor
// do not call rv() and rj() directly
function resolve(arg) {
finally();
rv(arg);
}
function reject(arg) {
finally();
rj(arg);
}
// cleanup code that is only ever called once
let finallyCalled = false;
function finally() {
if (!finallyCalled) {
clearTimeout(to);
finallyCalled = true;
}
}
const to = setTimeout(function(){
});
// elsewhere in this executor it should call resolve() or reject()
} catch(e) {
reject(e);
}
});
這是選項3的示例。
通常不建議使用延遲對象,但是它們確實允許您訪問.finally()
, resolve()
和reject()
都在同一范圍內,這會使某些事情變得更.finally()
(例如您要執行的操作)。
首先是一個簡單的Promise包裝器,它為我們提供了Deferred對象:
// can be used as either:
// let d = Promise.Deferred();
// let d = new Promise.Deferred();
// d.then(...)
// d.resolve(x);
// d.finally(...)
Promise.Deferred = function() {
if (!(this instanceof Promise.Deferred)) {
return new Promise.Deferred();
}
let p = this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
this.then = p.then.bind(p);
this.catch = p.catch.bind(p);
this.finally = p.finally.bind(p);
}
然后,您可以像這樣使用它:
// usage
function yourFunction() {
let d = new Promise.Deferred();
const to = setTimeout(...);
// other code here that will call d.resolve() or d.reject()
// cleanup code
d.finally(function() {
clearTimeout(to);
});
return d.promise;
}
此OP描述了Promises imo的其中一個丑陋之處,但這可能起作用:
return new Promise(function(resolve, reject {
const to = setTimeout(function(){
console.error('timed out');
reject('timed out');
});
doSomething(function(err, data){
if(!to._called){
resolve({to, data})
}
});
})
.then(function(v){
clearTimeout(v && v.to);
return v && v.data;
});
此解決方案的問題在於,那么的回調稱為異步,因此計時器可能會在過渡期間解析? 不確定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.