[英]JavaScript Promise resolve and reject function call sequence
我对以下简单的Promise示例感到困惑。
问题1:从控制台日志中,为什么在console.log(“200”)语句之后执行解析?
问题2:在onload()之前启用resolve()并使用无效的URL进行GET请求。 即使AJAX返回404,这次也不会调用拒绝,因为调用onload之前的解析。 为什么不拒绝被召唤?
https://jsfiddle.net/tut5va0m/3/
function get(url) {
// Return a new promise.
return new Promise(function(resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);
//Enable below for Question 2
//resolve(req.response);
req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
//Question 1
resolve(req.response);
console.log("200");
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};
// Make the request
req.send();
});
}
function resolve(data) {
console.log("Success!!! " + data);
}
function reject(data) {
console.log("Fail!!! " + data);
}
var url = '/echo/json';
var invalidUrl = '/abc'
get(url).then(resolve, reject);
//below is for Question 2
get(invalidUrl).then(resolve, reject);
对于问题A,解析使用process.nextTick() ,因此当前函数可能会在调用resolve callback之前完成。 这就是你在“成功”之前看到“200”的原因
对于问题B,承诺不能被解决和拒绝。 您必须选择或操作成功并解决或失败并被拒绝。 它可以是两者。
Promise通常用于异步操作,因此在执行promise处理程序之前将执行遵循promise操作的行(例如.then
)。 如果您使用回调函数,这是您应该熟悉的行为,例如req.onload
函数中包含的代码。 使用你的代码,你看到的是Promise.resolve
执行,然后是console.log
,然后链接到Promise的任何东西,在你的情况下,令人困惑的名称resolve
并reject
在此行注册:
get(url).then(resolve, reject);
更明确的是在afterResolve和afterReject之后重命名这些函数,因为那是在那些函数执行时。 如果要确保在解析或拒绝promise之后执行console.log
则需要将该语句放在那些promise-handling函数中,或者链接另一个函数并在那里执行。
get(url).then(resolve, reject).then(function(){
console.log('It worked')
})
至于你的第二个问题,承诺只能被解决或拒绝一次 。 您不能多次解决它,也不能在解决后拒绝它。 该承诺在解决或拒绝之后已经履行了职责,之后调用这些职能将不会做任何事情。 之后你需要创造新的承诺。
get(url).then(function successFirstRequest(){
return get(someOtherUrl)
}).then(function successSecondRequest(){
alert('Completed two network requests')
}).catch(err){
// one of your requests failed
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.