Promise 学习

235 阅读3分钟

一. Promise 是什么

为异步问题提供同步化的解决方案(解决回调地狱)

Promise 的三种状态
  • pending:等待状态。如,正在进行网络请求,或定时器未到时间
  • fulfilled(resolved):满足状态。如,当我们主动回调了 resolve 时,就处于该状态,且接下来会回调 .then()
  • rejected: 拒绝状态。如,当我们主动回调了 reject 时,就处于该状态,且接下来会回调 .catch()(如果有catch)
Promise 的常规写法
<!--常规写法-->

    new Promise((resolve, reject) => {
      setTimeout(() => {
        // -----1.响应成功时
        // resolve('响应成功时,调用 resolve')
        
        // -----2.响应失败时
        reject('响应失败时,调用 reject')
        
      }, 1000)
    }).then(success => {
      console.log(success); // 响应成功时,调用 resolve
    }).catch(error => {
      console.log(error); // 响应失败时,调用 reject
    })
<!--其他写法-->
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success')
        // reject('error')
      }, 1000)
    }).then(success => {
      console.log(success); // 响应成功时,调用 resolve
    }, error => {
      console.log(error);  // 响应失败时,调用 reject
    })

二. Promise.resolve() 和 Promise.reject()

1. Promise.resolve()

Promise 的语法糖,更简易的将参数创建为一个 Promise 对象

  • 当参数不带有 then 方法,则返回一个新的 Promise 对象,且其状态为 resolved
<!--Promise.resolve('erxun')  等价于   new Promise(resolve => resolve('erxun'))-->

const aa = Promise.resolve("erxun");
aa.then(res => {
  console.log('aa~~~'+res)  // aa~~~erxun 
})

const bb = new Promise(resolve => resolve('erxun'))
bb.then(res => {
  console.log('bb~~~'+res) // bb~~~erxun 
})

  • 当参数本身为 Promise 实例时,则直接返回此实例
const t = Promise.resolve('erxun')

console.log(Promise.resolve(t) === t);  // true

  • 参数是一个 thenable 对象(对象内具有 then 方法),则返回 Promise 实例的状态取决于 thenable 对象内的状态
<!-
    1. thenable 对象内的状态为 resolved,则 实例 p 的 状态为 resolved
-->

const thenable = {
  then: (resolve, reject) => {
    resolve("resolve-thenable");
  }
};

const p = Promise.resolve(thenable);
p.then(
  (res) => {
    console.log("resolved---" + res);  // resolved---resolve-thenable
  },
  (err) => {
    console.log("rejected---" + err);  // 不执行
  }
);

<!-
    2. thenable 对象内的状态为 rejected ,则 实例 p 的 状态为 rejected
-->

const thenable = {
  then: (resolve, reject) => {
    reject("reject-thenable");
  }
};

const p = Promise.resolve(thenable);
p.then(
  (res) => {
    console.log("resolved---" + res);   // 不执行
  },
  (err) => {
    console.log("rejected---" + err); //  rejected---resolve-thenable
  }
);


2.Promise.reject()

Promise.reject(rejectedInfo) 返回一个带有拒绝原因且状态为 rejected 的 Promise 对象


// from mdn

function resolved(result) {
  console.log('Resolved');
}

function rejected(result) {
  console.error(result);
}

Promise.reject(new Error('fail')).then(resolved, rejected);
// expected output: Error: fail

三. Promise.all() 和 Promise.any()

1. Promise.all() 可对多个 Promise 实例进行包装(包装成 iterable 类型),返回一个新的 Promise 实例 。
Promise.all([
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('erxun')
    }, 5000)
  }),
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(18)
    }, 1000)
  })
]).then(res => {
  console.log(res);  // ["erxun", 18]
}, error => {
  console.log(error);
})
  • success:当所有 Promise 实例的 resolve 都回调结束,则按 Promise 实例的顺序(空间顺序)返回一个包含 所有resolve 结果的数组
  • error:当有一个 promise 是 rejected ,则回调 reject 并且 reject 第一个抛出的错误信息
iterable 内部传递的不是 promise,则直接 resolve()
const p = Promise.all([1, true, "000"]);
p.then((res) => {
  console.log(res);  // [1, true, "000"]
});

iterable 内部传递的是空数组,则返回空数组
const p = Promise.all([]);
p.then((res) => {
  console.log(res);  // []
});

2. Promise.any()
  • 只要有一个 promise 成功,就返回那个成功的 Promise
const p1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "成功");
});
const p2 = Promise.resolve("erxun");

const p3 = Promise.reject("失败");

Promise.any([p3, p2, p1]).then(
  (res) => {
    console.log("resolve---" + res);  // resolve---erxun 
  },
  (error) => {
    console.log("reject-----" + error);  // 不执行
  }
);

  • 如果所有的 Promise 都失败,,就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起(???)
const p1 = new Promise((resolve, reject) => {
  setTimeout(reject, 500, "成功");
});
const p2 = Promise.reject("erxun");

const p3 = Promise.reject("失败");

Promise.any([p3, p2, p1]).then(
  (res) => {
    console.log("resolve---" + res);  // 不执行
  },
  (error) => {
    console.log("reject-----" + error);  // reject-----AggregateError: All promises were rejected 
  }
);

四. Promise.race(),返回一个 Promise 对象

假设有 Promise.race([p1,p2,p3]), iterable 中 p1,p2,p3 谁的结果先返回,就返回那个结果,不论结果 resolve 或 reject

// from mdn
var p1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "one");
});
var p2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, "two");
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value); // "two"
  // 两个都完成,但 p2 更快
});


var p3 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 100, "three");
});
var p4 = new Promise(function(resolve, reject) {
    setTimeout(reject, 500, "four");
});

Promise.race([p3, p4]).then(function(value) {
  console.log(value); // "three"
  // p3 更快,所以它完成了
}, function(reason) {
  // 未被调用
});



var p5 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "five");
});
var p6 = new Promise(function(resolve, reject) {
    setTimeout(reject, 100, "six");
});

Promise.race([p5, p6]).then(function(value) {
  // 未被调用
}, function(reason) {
  console.log(reason); // "six"
  // p6 更快,所以它失败了
});