Promise 是什么 Promise 是异步的一种解决方案 Promise 提供了三种状态:Pending(进行中),Fulfilled(执行态),Rejected(拒绝态) 一旦 Promise 状态被 resolve 或者 reject,就不能再更改状态 Promise 避免了函数的回调,解决了回调场景中的状态处理问题 Promise 没有避免回调嵌套问题,一旦创建一个 Promise 就会…

Promise 是什么

  1. Promise 是异步的一种解决方案
  2. Promise 提供了三种状态:Pending(进行中),Fulfilled(执行态),Rejected(拒绝态)
  3. 一旦 Promise 状态被 resolve 或者 reject,就不能再更改状态
  4. Promise 避免了函数的回调,解决了回调场景中的状态处理问题
  5. Promise 没有避免回调嵌套问题,一旦创建一个 Promise 就会立即执行,无法中途取消,当处于 pending 状态时,无法知道状态进展到哪块,是刚刚开始,还是即将结束
  6. promise 实例的状态变为 Resolved 或者 Rejected,就会触发 then 方法绑定的回调函数

尝鲜

// 基本用法
var promise = new Promise(function(resolve, reject) {
  if (true) {
    resolve(value);
  } else {
    reject(err);
  }
});
promise.then(
  function(value) {
    console.log('success');
  },
  function(err) {
    console.log('err');
  }
);
// Promise常用链式结构
new Promise()
  .then()
  .then()
  .catch();
// Promise新建之后就会立即执行
let promise0 = new Promise(function(resolve, reject) {
  console.log('promise0');
  resolve(1);
});
promise0.then(function(res) {
  console.log(res);
});
console.log(2);
// 输出
// promise0
// 2
// 1

一些钩子函数

  1. Promise.resolve()

    等价于 new Promise(resolve => resolve('foo')),Promise.resolve 在本轮事件循环后执行

// 定时器是下次事件循环,Promise.resolve是本次事件循环末
setTimeout(function() {
  console.log('three');
}, 0);
Promise.resolve().then(function() {
  console.log('two');
});
console.log('one');
// 输出
// one
// two
// three
let p0 = new Promise(resolve => {
  setTimeout(() => {
    let result = 'p0';
    resolve(result);
  }, 1000);
});
p0.then(result => {
  console.log(result);
});
// 输出
// p0
let p1 = Promise.resolve('p1');
p1.then(result => {
  console.log(result);
});
// 输出
// p1
  1. Promise.reject()

    有两种方式获取失败状态,等价于 new Promise(null,reject => reject('foo'))

Promise.reject('rejecterror').catch(e => {
  console.log(e);
});
// 输出
// rejecterror
// 第一种,通过then 第二个函数参数处理失败状态
let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    let result = 'p2error';
    reject(result);
  }, 100);
});
p2.then(
  result => {
    console.log('success:', result);
  },
  err => {
    console.log('fail:', err);
  }
);
// 第二种,通过catch来捕获异常或者失败状态
p2.then(result => {
  console.log('success:', result);
}).catch(err => {
  console.log('fail:', err);
});
// 如果既用第二个参数捕获异常,也用catch捕获异常,那么只被第一次捕获出异常
p2.then(
  result => {
    console.log('success:', result);
  },
  err => {
    console.log('fail-reject:', err);
  }
).catch(err => {
  console.log('fail-catch', err);
});
// 输出
// fail: p2error
// fail-reject: p2error
// fail: p2error
let p3 = Promise.reject('p3error');
p3.then(null, result => console.log('fail:', result));
p3.then().catch(result => console.log('error:', result));
// 输出
// fail: p3error
// error: p3error
  1. Promise.prototype.catch()

    一般要用 catch 捕获 catch 前面所有 resolved 或者 rejected 的异常

// 直接捕获reject
let p4 = new Promise((resolve, reject) => {
  reject('p4error');
});
p4.then(result => {
  console.log('success:', result);
}).catch(result => {
  console.log('error:', result);
});
// 输出
// error: p4error
// 捕获onRejected中的异常
// 捕获onResolved中的异常同理
let p5 = new Promise((resolve, reject) => {
  reject('p5error111');
});
p5.then(null, err => {
  console.log('reject error:', err);
  throw new Error('我是onResolved状态下的异常');
}).catch(err => {
  console.log('Custom error:', err);
});
// 输出
// reject error: p5error
// Custom error: Error: 我是onResolved状态下的异常
// 如果状态已经变成resolved,再抛的异常,是无法捕获的
const p6 = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');
});
p6.then(function(value) {
  console.log(value);
}).catch(function(error) {
  console.log(error);
});
// 输出
// ok
// 如果状态已经变成resolved,再抛的冒泡到最外层异常,就捕获不到异常
const p7 = new Promise(function(resolve, reject) {
  resolve('ok');
  setTimeout(function() {
    throw new Error('test');
  }, 100);
});
p7.then(function(value) {
  console.log(value);
}).catch(err => {
  console.log(err);
});
// 输出
// ok
// Uncaught Error: test
// Promise内部的异常不会影响Promise外部的代码
const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    try {
      // 这个异常会被捕获
      resolve(x + 2);
    } catch (err) {
      console.log(err);
    }
    // 下面一行会报错,因为y没有声明
    resolve(y + 2);
  });
};
someAsyncThing()
  .then(function() {
    console.log('everything is great');
  })
  .catch(err => {
    console.log(err);
  });
// 输出
// ReferenceError: x is not defined
// ReferenceError: y is not defined
// 如果是catch后面的异常,catch是捕获不到的
Promise.resolve()
  .catch(function(error) {
    console.log('oh no', error);
  })
  .then(function() {
    throw new Error('我是catch后面的异常');
  });
// 输出
// Uncaught (in promise) Error: 我是catch后面的异常
//  catch中的异常,必须在catch后面一直加个catch才能捕获
const someAsyncThing2 = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};
someAsyncThing2()
  .then(function() {
    return someOtherAsyncThing();
  })
  .catch(function(error) {
    console.log('oh no', error);
    // 下面一行会报错,因为 y 没有声明
    y + 2;
  })
  .then(function() {
    console.log('carry on');
  })
  .catch(err => {
    console.log(err);
    z + 2;
  });
// 输出
// oh no ReferenceError: x is not defined
// ReferenceError: y is not defined
// promise.js:205 Uncaught (in promise) ReferenceError: z is not defined
  1. Promise.finally()

    finally 在执行完 then、catch 后

// finally没办法知道当前状态时resolved还是rejected,finally是与状态无关的,不依赖Promise执行
var p8 = new Promise((resolve, reject) => {
  resolve('p8ok');
});
p8.then(result => {
  console.log('resolve:', result);
})
  .catch(err => {
    console.log(err);
  })
  .finally(() => {
    console.log('finally');
    throw new Error('我是finally的错误');
  })
  .catch(err => {
    console.log(err);
  });
// 输出
// resolve: p8ok
// finally
// Error: 我是finally的错误
  1. Promise.all()

    Promise 用户将多个 Promise 实例,包装成一个新的 Promise 实例,const p = Promise.all([p1, p2, p3]);

// 当p1 p2 p3 的状态都变成resolved,那么p的状态就是resolved
// 当p2 p2 p3 的一个状态是rejected,那么p的状态就是rejected
const promiseMap = [2, 3, 5, 7, 11, 13].map(function(id) {
  return new Promise((reslove, reject) => {
    if (id == 2) {
      reject(id);
    } else {
      reslove(id);
    }
  });
});
Promise.all(promiseMap)
  .then(result => {
    console.log('promiseMap:', result);
  })
  .catch(err => {
    console.log('一个状态是rejected,那么p的状态就是rejected', err);
  });
// 输出
// 一个状态是rejected,那么p的状态就是rejected 2
  1. Promise.race

    将多个 Promise 实例,包装成一个新的 Promise 实例

// 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给promiseMap2的回调函数
const promiseMap2 = [2, 3].map(function(id) {
  return new Promise((reslove, reject) => {
    if (id == 3) {
      reject(id);
    } else {
      reslove(id);
    }
  });
});
Promise.race(promiseMap2)
  .then(result => {
    console.log('promiseMap:', result);
  })
  .catch(err => {
    console.log('一个状态是rejected,那么p的状态就是rejected', err);
  });
// 无输出

Promise 封装 ajax

const getData = function() {
  var url = 'www.example.com/getData';
  return new Promise((resolve, reject) => {
    const func = function() {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status == 200) {
        resolve(this.response);
      } else {
        reject(new Error(this.status));
      }
    };
    const client = new XMLHttpRequest();
    client.open('GET', url);
    client.onreadystatechange = func;
    (client.responseType = 'json'), client.setRequestHeader('Accept', 'application/json');
    client.send();
  });
};
getData()
  .then(
    res => {
      console.log(res);
    },
    err => {
      console.log('reject', err);
    }
  )
  .catch(err => {
    console.log('catch', err);
  })
  .finally(() => {
    throw new Error('finally中的异常');
  })
  .catch(err => {
    console.log('finallyXCatch', err);
  });
// 输出
// reject Error: 0
// finallyXCatch Error: finally中的异常

暂无评论