繁体   English   中英

JavaScript Promise解析并拒绝函数调用序列

[英]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的任何东西,在你的情况下,令人困惑的名称resolvereject在此行注册:

get(url).then(resolve, reject);

更明确的是在afterResolveafterReject之后重命名这些函数,因为那是在那些函数执行时。 如果要确保在解析或拒绝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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM