promise

Promise

  • 基本使用

    //resolve和reject是JavaScript引擎提供的两个函数
    const promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    
    //用then方法分别指定resolved状态和rejected状态的回调函数
    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    });
    

    then方法可以接受两个回调函数作为参数,第一个回调函数是promise对象的状态变成resolved时调用,第二个回调函数是promise对象的状态变成rejected时调用,第二个函数是可选的,不一定提供。这两个函数都接受promise对象传出的值作为参数。

    function timeout(ms){
        return new Promise((resolve,reject)=>{
            setTimeout(resolve,ms,'done');
        });
    }
    timeout(100).then((value)=>{
        console.log(value);
    });
    

    promise新建后就会立即执行

    let promise = new Promise(function(resolve,reject){
        console.log('Promise');
        resolve();
    });
    promise.then(function(){
        console.log('resolved.');
    });
    console.log('Hi!');
    

    代码执行后,输出顺序如下:

    Promise

    Hi!

    resolved.

    异步加载图片的例子

  function loadImageAsync(url){
      return new Promise(function(resolve,reject){
          const image = new Image();
          image.onload = function(){
              resolve(image);
          };
          
          image.onerror = functioin(){
              reject(new Error('Could not load image at'+url));
          };
          image.src = url;
      });
  }

以上代码,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。

promise对象实现的AJAX操作的例子

  const getJSON = function(url){
      const promise = new Promise(function(resolve,reject){
          const handler = function(){
              if(this.readyState !== 4){
                  return;
              }
              if(this.status === 200){
                  resolve(this.response);
              } else {
                  reject(new Error(this.ststusText));
              }
          };
          cosnt client = new XMLHttpRquest();
          client.open("GET",url);
          client.onreadystatechange = handler;
          client.responseType = 'json';
          client.setRequestHeader('Accept','application/json');
          client.send();
      });
      return promise;
  };
  getJSON('/posts.json').then(function(json){
      console.log('Contents:'+json);
  },function(error){
      console.log('出错了',error);
  });

getJSON是对XMLHttpRequest对象的封装,用于发出一个针对JSON数据的HTTP请求,并且返回一个promise对象。

一般来说,调用resolve或reject以后,promise的使命就完成了,后续操作应该写在then方法里面,而不是直接写在resolve或reject的后面。所以最好在它们前面加上return语句,这样就不会有意外

  new Promise((resolve,reject)=>{
      return resolve(1);
      //后面的语句不会执行
      console.log(2);
  });
  • 状态

    三种状态:pending(进行中)、fufilled(已成功)、rejected(已失败)

    只能从第一种状态到第二或第三种状态,状态一旦改变,就不会再变了

  • 常用方法

    • Promise.all

    Promise.all方法用于将多个promise实例,包装成一个新的Promise实例。

    const p = Promise.all([p1,p2,p3]);
    

    p的状态由p1p2p3决定,任意一个被rejected,p的状态就会变成rejected,否则会变成fullfilled状态。

    • Promise.race

    Promise.race方法用于将多个promise实例,包装成一个新的Promise实例。

    const p = Promise.race([p1,p2,p3]);
    

    只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    • promise和generator的结合

      function getFoo(){
          return new Promise(function(resolve,reject){
              resolve('foo');
          });
      }
      const g = function* (){
          try{
              const foo = yield getFoo();
              console.log(foo);
          } catch (e){
              console.log(e);
          }
      }
      function run (generator){
          const it = generator();
          function go(result){
              if(result.done) return result.value;
              return result.value.then(function(value){
                  return go(it.next(value));
              },function(error){
                  return go(it.throw(error));
              });
          }
          go(it.next());
      }
      run(g);
      

​ 以上代码的generator函数g之中,有一个异步操作getFoo,它返回的就是一个promise对象。函数run用来处理这个promise对象,并调用下一个next方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值