[JavaScript]异步 & Promise

62 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

异步

  • JavaScript的执行环境是「单线程」。

  • 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程。

  • 异步模式可以一起执行多个任务

  • JS中常见的异步调用:

    • 定时任何
    • ajax
    • 事件函数

Promise 基本 API

实例方法

.then()

  • 得到异步任务正确的结果

.catch()

  • 获取异常信息

.finally()

  • 成功与否都会执行(不是正式标准)
  
  <script type="text/javascript">
    /*
      Promise常用API-实例方法
    */
    // console.dir(Promise);
    function foo() {
      return new Promise(function(resolve, reject){
        setTimeout(function(){
          // resolve(123);
          reject('error');
        }, 100);
      })
    }
    // foo()
    //   .then(function(data){
    //     console.log(data)
    //   })
    //   .catch(function(data){
    //     console.log(data)
    //   })
    //   .finally(function(){
    //     console.log('finished')
    //   });
​
    // --------------------------
    // 两种写法是等效的
    foo()
      .then(function(data){
        # 得到异步任务正确的结果
        console.log(data)
      },function(data){
        # 获取异常信息
        console.log(data)
      })
      # 成功与否都会执行(不是正式标准) 
      .finally(function(){
        console.log('finished')
      });
  </script>

静态方法

.all()

  • Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定。

.race()

  • Promise.race方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilledrejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数。
  <script type="text/javascript">
    /*
      Promise常用API-对象方法
    */
    // console.dir(Promise)
    function queryData(url) {
      return new Promise(function(resolve, reject){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
          if(xhr.readyState != 4) return;
          if(xhr.readyState == 4 && xhr.status == 200) {
            // 处理正常的情况
            resolve(xhr.responseText);
          }else{
            // 处理异常情况
            reject('服务器错误');
          }
        };
        xhr.open('get', url);
        xhr.send(null);
      });
    }
​
    var p1 = queryData('http://localhost:3000/a1');
    var p2 = queryData('http://localhost:3000/a2');
    var p3 = queryData('http://localhost:3000/a3');
     Promise.all([p1,p2,p3]).then(function(result){
       //   all 中的参数  [p1,p2,p3]   和 返回的结果一 一对应["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
       console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"]
     })
    Promise.race([p1,p2,p3]).then(function(result){
      // 由于p1执行较快,Promise的then()将获得结果'P1'。p2,p3仍在继续执行,但执行结果将被丢弃。
      console.log(result) // "HELLO TOM"
    })
  </script>