请考虑以下代码段:
var xmldoc = new XmlDocument();
xmldoc.LoadXml(x);
var r = xmlDoc.SelectNodes("//X/C | //X/A");
foreach (XmlNode i in r)
Debug.WriteLine(i.Value);
其执行将产生以下输出:
function func1() {
return Promise.resolve();
}
function func2() {
func1()
.then(res => console.log("In func2 'then'"))
.catch(err => console.log("In func2 'catch"));
}
function func3() {
Promise.resolve()
.then(() => {
func2();
})
.then(() => {
console.log("In func3 'then'");
});
}
func3();
如果将In func2 'then'
In func3 'then'
的返回值替换为func1
,如下所示:
Promise.reject()
,promise的回调将以不同的顺序执行,从而产生:
function func1() {
return Promise.reject();
}
function func2() {
func1()
.then(res => console.log("In func2 'then'"))
.catch(err => console.log("In func2 'catch"));
}
function func3() {
Promise.resolve()
.then(() => {
func2();
})
.then(() => {
console.log("In func3 'then'");
});
}
func3();
这是在节点和镶边中观察到的输出顺序。
这是怎么回事?为什么In func3 'then'
In func2 'catch
的'catch'与'then'具有不同的执行优先级?
该代码段很奇怪,但我想知道为什么会发生这种行为-是某些实施细节的附带影响,还是一般调度策略的说明?
答案 0 :(得分:1)
在func3
中初始化的承诺链实际上并未与在func2
中初始化的承诺链连接;与您的
.then(() => {
func2();
})
由于未返回func2
的结果,因此func2
的承诺未连接到func3
中的链。您所看到的时间可以归结为毫秒级的时间:如果一个Promise解析(或拒绝),而另一个未与它链接的Promise 基本上同时解析(或拒绝),则该链的{{1 }}或.then
首先运行?这不是直观的,也不是您的代码应依赖的逻辑。
如果在使用.catch
时在.then
中切换.catch
和func2
,您将看到与第二个代码相同的行为- Promise.resolve
日志在func3
日志之前运行。
func2
最佳解决方案:永远不依赖微秒计时,而是始终通过function func1() {
return Promise.resolve();
}
function func2() {
func1()
.catch(err => console.log("In func2 'catch"))
.then(res => console.log("In func2 'then'"))
}
function func3() {
Promise.resolve()
.then(() => {
func2();
})
.then(() => {
console.log("In func3 'then'");
});
}
func3();
链接您的Promises(无论您是处于return
之类的独立函数中,还是处于{{1}内部) }),因此一切都链接在一起,事情将完全可预测:
func2
现在,很明显.then
的链将始终完全完成,然后再移至function func1() {
return Promise.reject();
}
function func2() {
// return the chain:
return func1()
.then(res => console.log("In func2 'then'"))
.catch(err => console.log("In func2 'catch"));
}
function func3() {
// return the chain (just in case consumers of func3 want to use the chain):
return Promise.resolve()
.then(() => {
// return the chain:
return func2();
})
.then(() => {
console.log("In func3 'then'");
});
}
func3();
(无论是否有错误),因为func2
链是在In func3 'then'
的{{1}}内部返回。