首页 文章

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

提问于
浏览
1

我对以下简单的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);

2 回答

  • 1

    Promise通常用于异步操作,因此在promise处理程序执行之前将执行一个遵循promise操作的行(例如 .then ) . 如果您使用回调函数(例如 req.onload 函数中包含的代码),这种行为应该是您熟悉的 . 使用你的代码,你所看到的是 Promise.resolve 正在执行,然后 console.log ,然后链接到Promise的任何东西,在你的情况下,在这一行注册了令人困惑的名字 resolvereject

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

    更明确的是在afterResolve和afterReject之后重命名这些函数,因为那是在那些函数执行时 . 如果要确保在解析或拒绝promise之后执行 console.log ,则需要将该语句放在那些promise-handling函数中,或者链接另一个函数并在那里执行 .

    get(url).then(resolve, reject).then(function(){
        console.log('It worked')
    })
    

    至于你的第二个问题,承诺只能被解决或拒绝一次 . 你可以't resolve it multiple times, nor can you reject it after it'已经解决了 . 这个承诺在之后做任何事情后都履行了职责 . 之后你需要创造新的承诺 .

    get(url).then(function successFirstRequest(){
        return get(someOtherUrl)
    }).then(function successSecondRequest(){
       alert('Completed two network requests')
    }).catch(err){
       // one of your requests failed
    })
    
  • 2

    对于问题A,解析使用process.nextTick(),所以's possible that current function will finish before resolve callback will be called. It'是你在"Success"之前看到"200"的原因

    对于问题B,承诺不能被解决和拒绝 . 您必须选择或操作成功并解决或失败并被拒绝 . 它可以是两者 .

相关问题