我以前問這裏發現了一個問題: Retaining Data across multiple promise chains節點未處理的承諾問題
我最終使用T.J.克羅德的答案爲我的基本代碼,並做了許多改變。但是我注意到節點中有些奇怪的東西,我似乎無法克服。我回到了他提供的基本代碼,這個問題似乎也在那裏。
這裏是例子:
"use strict";
// For tracking our status
class Status {
constructor(total = 0, count = 0) {
this.id = ++Status.id;
this.total = total;
this.count = count;
}
addCall() {
++this.total;
return this;
}
addProgress() {
++this.count;
return this;
}
toString() {
return `[S${this.id}]: Total: ${this.total}, Count: ${this.count}`;
}
}
Status.id = 0;
// The promise subclass
class RepoPromise extends Promise {
constructor(executor) {
super(executor);
this.s = new Status();
}
// Utility method to wrap `then`/`catch` callbacks so we hook into when they're called
_wrapCallbacks(...callbacks) {
return callbacks.filter(c => c).map(c => value => this._handleCallback(c, value));
}
// Utility method for when the callback should be called: We track that we've seen
// the call then execute the callback
_handleCallback(callback, value) {
this.s.addProgress();
console.log("Progress: " + this.s);
return callback(value);
}
// Standard `then`, but overridden so we track what's going on, including copying
// our status object to the new promise before returning it
then(onResolved, onRejected) {
this.s.addCall();
console.log("Added: " + this.s);
const newPromise = super.then(...this._wrapCallbacks(onResolved, onRejected));
newPromise.s = this.s;
return newPromise;
}
// Standard `catch`, doing the same things as `then`
catch(onRejected) {
this.s.addCall();
console.log("Added: " + this.s);
const newPromise = super.catch(...this._wrapCallbacks(onRejected));
newPromise.s = this.s;
return newPromise;
}
}
// Create a promise we'll resolve after a random timeout
function delayedGratification() {
return new Promise(resolve => {
setTimeout(_ => {
resolve();
}, Math.random() * 1000);
});
}
// Run! Note we follow both kinds of paths: Chain and diverge:
const rp = RepoPromise.resolve('Test');
rp.then(function(scope) {
return new Promise((resolve, reject) => {
console.log(' Rejected')
reject(scope)
})
})
.catch(e => {console.log('Never Makes it')})
,當我跑這跟:node test.js
我得到以下輸出
Added: [S1]: Total: 1, Count: 0
Added: [S1]: Total: 2, Count: 0
Added: [S1]: Total: 3, Count: 0
Progress: [S1]: Total: 3, Count: 1
Rejected
(node:29364) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Test
(node:29364) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
注意,控制檯日誌"never makes it"
不存在,還要注意,我已經解決了catch
運行兩次的問題,因爲它是then(null, function(){})
的簡單語法糖,因此您可以忽略該問題。
爲什麼catch沒有按照我的預期工作?當我以正常的承諾來做到這一點時,沒有問題,如下所示。所以我知道_wrapCallbacks
導致這個問題,我只是不知道爲什麼,或者如何解決這個問題。
const rp = Promise.resolve('Test');
rp.then(function(scope) {
return new Promise((resolve, reject) => {
console.log(' Rejected')
reject(scope)
})
})
.catch(e => {console.log('Makes it')})
是的,我已經放棄了重寫的抓取,謝謝你,我總是困惑,爲什麼他使用過濾器,但我現在看到。這正是我的問題,我知道這是具有該功能的東西。我想我需要重新學習過濾器/地圖。謝謝! – Krum110487
Tbh,我根本不會使用'filter' /'map',只是調用'super.then(this._wrapCallback(onFulfilled),this._wrapCallback(onRejected));' – Bergi
同意,我只是意識到我對filter/map有一個基本的誤解,因爲我很少使用它們,知道null被刪除會幫助我理解發生了什麼。 – Krum110487