Javascript 跨多个承诺链保留数据
我正在学习承诺,所以我决定尝试扩展它们。一切都正常,只是我很难弄清楚如何使值在所有函数中持久化 我的目标是从这个承诺中找到被调用函数的数量,但是每次调用都会创建一个新函数,我很难找到一种方法来传递值。我尝试添加一个构造函数,该构造函数将传入一个值,但它似乎并不像我预期的那样工作。我想这是因为我误解了“这个”的范围 总而言之,我的每个函数“init”、“add”和“commit”都应该在“totalnumber of steps”变量前面加上1,在本例中,现在的变量是“i”。有了这些,我想说,我在第1步,第3步,第2步,第3步等等Javascript 跨多个承诺链保留数据,javascript,scope,promise,Javascript,Scope,Promise,我正在学习承诺,所以我决定尝试扩展它们。一切都正常,只是我很难弄清楚如何使值在所有函数中持久化 我的目标是从这个承诺中找到被调用函数的数量,但是每次调用都会创建一个新函数,我很难找到一种方法来传递值。我尝试添加一个构造函数,该构造函数将传入一个值,但它似乎并不像我预期的那样工作。我想这是因为我误解了“这个”的范围 总而言之,我的每个函数“init”、“add”和“commit”都应该在“totalnumber of steps”变量前面加上1,在本例中,现在的变量是“i”。有了这些,我想说,我在
class Repo {
constructor(setup) {
this.s = {};
this.s._progress = { "total":0, "count":0 };
this.s._logging = { "enabled":true, "location":"console", "pretty":true, "verbose":false, "tabCount":0 };
this.s._remoteInfo = { "name":"", "url":"" };
this.s._localInfo = { "path":"" };
this.s._logReset = () => {
this.s._logging.tabCount = 0;
};
this.s._log = (message, tabCount) => {
if(this.s._logging.enabled) {
let tabs = '';
if(this.s._logging.pretty) {
for(let i = 0; i < tabCount; i++) { tabs = tabs + '\t' };
}
if(this.s._logging.location == 'console') { console.log(tabs, message); }
else {
//TODO: implement the file location to output
}
}
};
this.s._progressReset = () => {
this.s._progress.total = 0;
this.s._progress.count = 0;
};
this.s._addProgressTotal = () => {
this.s._progress.total++;
console.log(this.s._progress.total)
}
this.s._addProgress = () => {
this.s._progress.count++;
console.log('Progress is ' + this.s._progress.count + ' out of ' + this.s._progress.total)
}
}
//Starts the promise chain and passes in the settings to be used.
start() {
this.s._logReset();
this.s._progressReset();
return new RepoPromise((resolve, reject) => {
this.s._log('Start Log: <time>',0)
resolve(this.s);
});
}
}
class RepoPromise extends Promise {
constructor(executor, val) {
let e = executor || function (res, rej) { res('')};
super((resolve, reject) => {
return e(resolve, reject);
});
this.i = val || 0;
}
end() {
const returnValue = super.then((s) => {
return new RepoPromise((resolve, reject) => {
s._log('End Log: <time>',0)
resolve(s);
}, this.i);
});
return returnValue;
}
init() {
//I know I need to add 1 to "i" here, but it won't work
const returnValue = super.then((s) => {
return new RepoPromise((resolve, reject) => {
s._log('git init',1);
s._addProgress();
resolve(s, '')
}, ++this.i);
});
return returnValue;
};
add() {
//I know I need to add 1 to "i" here, but it won't work
const returnValue = super.then((s) => {
return new RepoPromise((resolve, reject) => {
setTimeout(() => {
s._log('git add',1);
s._addProgress();
resolve(s,'');
//reject('Add Failed')
}, Math.random() * (10000 - 1000) + 1000);
},++this.i);
});
return returnValue;
}
commit() {
//I know I need to add 1 to "i" here, but it won't work
const returnValue = super.then((s) => {
return new RepoPromise((resolve, reject) => {
setTimeout(() => {
s._log('git commit -m "message"',1);
s._addProgress();
resolve(s, 'Finished');
}, Math.random() * (5000 - 1000) + 1000);
}, ++this.i);
});
return returnValue;
}
then(onFulfilled, onRejected) {
const returnValue = super.then(onFulfilled, onRejected);
return returnValue;
}
}
正如您所指出的,这个链条中没有一个承诺,每个
然后和捕获都会返回一个新的承诺。因此,不要试图将状态保留在RepoPromise
中,而是将其保留在通过链的对象中作为分辨率值:s
Re是RepoPromise
构造函数的第二个参数:您不能可靠地执行此操作,因为您无法控制每次调用该构造函数。请记住,当您调用然后
或catch
时,将调用该构造函数。这是在s
上传递值的另一个原因。:-)为了完整起见,这里举例说明了在Promise
中调用构造函数的事实:
类MyPromise扩展了Promise{
构造函数(…参数){
超级(…args);
log(“调用MyPromise构造函数”);
}
}
我的承诺
。然后(val=>val)
。然后(val=>val)
。然后(val=>val)代码>谢谢您的代码建议,我将进行更改。我发现使用“resolve”来传递设置(“S”)的唯一问题是,它强制它位于“then”呼叫中,这不允许我提前计算呼叫数。我需要在每次调用的开始处添加值,然后才能返回链接。所以,除非有一个技工来做,否则我不知道怎么做。这就是为什么我尝试采用构造函数的方式,这显然给我带来了问题。@Krum110487:恐怕我不明白“提前”将调用相加是什么意思……?所以当调用add/init/commit时,我会在我希望将计数加1的地方加上注释。如果加法发生在那里,它会在第一次调用结束之前加上3次,因为我们正在等待promise回调。因为Add/init/commit在返回承诺后将继续进行,所以我希望计数发生在Add/init/commit函数本身,而不是它们返回的承诺中。@Krum110487:我可能太密集了。您说过“我的目标是从这个承诺中找到被调用函数的数量……”您具体想计算对哪些函数的调用<代码>添加
?或者然后
/捕获
?(在您的示例中,commit
之后,只有最后一个catch
,所以您的目标可能是计算添加
调用数?)!要是当初我能说得这么简单就好了。
var p = new Repo('')
.start()
.init()
.add()
.commit()
.end()
.catch(
x => {console.log('it broke: ' + x)}
);