promise使用经验,前前后后经过好几次总结,才最终由众多变化莫测的结论中,抽象出一般的结论;并且这个结论也和promise源码一致;结论放在最后了,本文的案例可能不足以支撑得出这个结论,大家自己自行测试;如有疑问,也可以与作者讨论;

一般用法

var promise = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});

或者

function createPromise(){
  return new Promise(function (resolve, reject) {
     resolve(request.responseText);
    });
}

链式操作

创建首个 Promise

var p = new Promise(function (resolve, reject) {
    log('start new Promise...');
    resolve(123);
});
p.then().then()....

或者

var p=Promise.resolve('13');
或者
var p=Promise.resolve('13');
p.then().then()

then 链

then 函数是可以有两个参数函数的,fulfilled rejected,一般只写一个函数 fulfilled;

  • 如果两个参数函数,都是同步函数,则 then 函数按照顺序执行;如果上一个 then 函数执行的结果,不返回 promise,则默认执行 fulfilled 函数;

    var promise = Promise.reject("1");
    
    promise
      .then(
        config => {
          console.log("2");
        },
        err => {
          console.log("3");
        }
      )
      .then(
        config => {
          console.log("4");
        },
        err => {
          console.log("5");
        }
      )
      .then(
        config => {
          console.log("6");
        },
        err => {
          console.log("7");
        }
      );

    输出:

    3
    4
    6

[========]

var promise = Promise.resolve("1");

promise
  .then(
    config => {
      console.log("2");
    },
    err => {
      console.log("3");
    }
  )
  .then(
    config => {
      console.log("4");
    },
    err => {
      console.log("5");
    }
  )
  .then(
    config => {
      console.log("6");
    },
    err => {
      console.log("7");
    }
  );

输出:

2
4
6

[========]

var promise = Promise.reject("1");

promise
  .then(
    config => {
      console.log("2");
    },
    err => {
      console.log("3");
    }
  )
  .then(() => Promise.reject("0"))
  .then(
    config => {
      console.log("6");
    },
    err => {
      console.log("7");
    }
  )
  .then(
    config => {
      console.log("8");
    },
    err => {
      console.log("9");
    }
  );

输出

3
7
8

[===]

var promise = Promise.reject("1");

promise
  .then(
    config => {
      console.log("2");
    },
    err => {
      console.log("3");
    }
  )
  .then(() => {
    throw new Error("sorry");
  })
  .then(
    config => {
      console.log("6");
    },
    err => {
      console.log("7");
    }
  )
  .then(
    config => {
      console.log("8");
    },
    err => {
      console.log("9");
    }
  );

输出

3
7
8
  • 如果两个参数函数,含有异步函数(setTimeout 等),则 then 函数按照顺序触发;
var promise = Promise.reject("1");

promise
  .then(
    config => {
      console.log("2");
    },
    err => {
      console.log("3");
    }
  )
  .then(() => {
    console.log("trigger timeout");
    setTimeout(() => {
      console.log("exec timeout");
    });
  })
  .then(
    config => {
      console.log("6");
    },
    err => {
      console.log("7");
    }
  )
  .then(
    config => {
      console.log("8");
    },
    err => {
      console.log("9");
    }
  );

输出

3
trigger timeout
6
8
exec timeout
  • 如果两个参数函数,返回 promise,则后面的 then 会等待前面的 promise 执行完之后,才去执行;

    // 0.5秒后返回input*input的计算结果:
    function multiply(input) {
      return new Promise(function(resolve, reject) {
        log("calculating " + input + " x " + input + "...");
        setTimeout(resolve, 500, input * input);
      });
    }
    
    // 0.5秒后返回input+input的计算结果:
    function add(input) {
      return new Promise(function(resolve, reject) {
        log("calculating " + input + " + " + input + "...");
        setTimeout(resolve, 500, input + input);
      });
    }
    
    var p = new Promise(function(resolve, reject) {
      log("start new Promise...");
      resolve(123);
    });
    
    p.then(multiply)
      .then(add)
      .then(multiply)
      .then(add)
      .then(function(result) {
        log("Got value: " + result);
      });
    // 在新增一个例子
    var promise = Promise.reject("1");
    
      promise
        .then(
          (config) => {
            console.log("2");
          }
        )
        .then(
          (config) => {
            console.log("6");
          //let a = {};
          //console.log(a.list.name);
          return a;
          },
        )
        .then()
        .then()
        .then(
          (config) => {
            console.log("8");
    
          },
          ()=>{
              console.log('a is wrong');
          }
        ).catch(err=>{
        console.log('enter err');
        console.log(err);
        })
    
        // 结论
        // a is wrong

    promise 链式操作与其他 JS

    const f = () => console.log("now");
    Promise.resolve().then(f);
    console.log("next");
    
    // next
    // now

    这个问题涉及到 这一次,彻底弄懂 JavaScript 执行机制

最终总结出的一般性规律

then()函数会返回一个和原来不同的新的Promise(不管then有没有函数方法 或者有函数方法,但没有return 或者 return 非promise),状态是 根据上一个then()函数返回的promise状态,它有没有接住(定义相应的函数)来定;

如果没接住,则其返回值和上一个返回值 状态相同;如果接住了,没有返回值 或者 返回值是非promise 则是fullfilled状态;除非抛错、或者 return 一个rejected状态的Promise(只有这两种情形);如果一直没有接住,则catch接手;


前端熟练工
1.8k 声望66 粉丝

要做前端架构师的正在前行的人


« 上一篇
axios 源码学习
下一篇 »
axios 学习