Promise

promise

异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更加合理且更强大

有三种状态:
1. pending [待定] 初始状态
2. fulfilled [实现] 操作成功
3. rejected [拒绝] 操作失败

var promise = new Promise(function(resolve,reject){
    if(/*异步操作*/){
        resolve(value);
    } else{
        reject(error);
    }
})

当promise状态发生改变,就会触发then()里的响应函数处理后续步骤
promise.then(函数)

状态改变只有两种可能:

  1. 从pending变为fulfilled
  2. 从pending变为rejected
var promise = new Promise(function(resolve,reject){
    if(/*异步操作*/){
        resolve(value);
    } else{
        reject(error);
    }
}).then(function(result){
    console.log(result)
},(function(error){
    console.log(error)
})
  • .then 的第一个参数是一个函数,该函数将在 promise resolved 后运行并接收结果。

  • .then 的第二个参数也是一个函数,该函数将在 promise rejected 后运行并接收 error。

如果我们只需要成功的结果 .then()的函数参数可以只有一个

let promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("success"), 1000);
});

promise.then(result=>alert(result)); // 1 秒后显示 "success"

如果我们只需要失败结果 可以用 .catch() 代替.then()

let promise = new Promise((resolve, reject) => {
        setTimeout(() => reject("fail"), 1000);
      });

promise.catch(error=>alert(error)); // 1 秒后显示 "fail"

promise链

每个对 .then 的调用都会创建并返回了一个新的 promise,因此我们可以在其之上调用下一个 .then

new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

  alert(result); // 1
  return result * 2;

}).then(function(result) { // (***)

  alert(result); // 2
  return result * 2;

}).then(function(result) {

  alert(result); // 4
  return result * 2;

});

上面的代码与下面的代码效果相同

new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000);

}).then(function(result) {

  alert(result); // 1

  return new Promise((resolve, reject) => { // (*)
    setTimeout(() => resolve(result * 2), 1000);
  });

}).then(function(result) { // (**)

  alert(result); // 2

  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });

}).then(function(result) {

  alert(result); // 4

});

这里第一个 .then 显示 1 并在 (*) 行返回 new Promise(…)。1 秒后它会进行 resolve,然后 result(resolve 的参数,在这里它是 result*2)被传递给第二个 .then 的处理程序(handler)。这个处理程序(handler)位于 (**) 行,它显示 2,并执行相同的动作(action)。

所以输出与前面的示例相同:1 → 2 → 4,但是现在在每次 alert 调用之间会有 1 秒钟的延迟。

返回 promise 使我们能够构建异步行为链。

promise.all

Promise.all([])可以将多个promise实例包装成一个新的promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败时返回的是最先被reject失败状态的值。

let p1 = new Promise((resolve,reject)=>{
    resolve('成功了')
})
let p2 = new Promise((resolve,reject)=>{
    resolve('success')
})
let p3 = new Promise((resolve,reject)=>{
   reject('失败了')
})


Promise.all([p1,p2]).then((result)=>{
    consle.log(result)  //['成功了','success'] 结果数组的顺序和all里的数组顺序一致
}).catch((error)=>{
    consle.log(error)  
})

Promise.all([p1,p3,p2]).then((result)=>{
    consle.log(result)  //['成功了','success'] 结果数组的顺序和all里的数组顺序一致
}).catch((error)=>{
    consle.log(error)  //'失败了',其他成功结果被忽略
})

Promise.race

顾名思义,Promise.race就是赛跑的意思,意思就是说,Promise.race([p1,p2,p3])里面哪个结果获得的块,就返回哪个结果,不管结果本身是成果状态还是失败状态。

let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('success')
    },1000)
})

let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('成功了')
    },500)
})

let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
       reject('fail')
    },2000)
})

Promise.race([p1,p2,p3]).then((result)=>{
    console.log(result)  // '成功了',因为p2最先完成
}).catch((error)=>{
    consle.log(error)
})

async/await

Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。

async

在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被包装在一个 resolved 的 promise 中。

async function f() {
  return 1;
}

f().then(alert); // 1

这个函数返回一个结果为 1 的 resolved promise,如同下面的代码

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
await

await 只在 async 函数内工作
关键字 await 让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // 等待,直到 promise resolve (*)

  alert(result); // "done!"
}

f();

这个函数在执行的时候,“暂停”在了 (*) 那一行,并在 promise settle 时,拿到 result 作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”。
await相当于promise.then

如果一个 promise 正常 resolve,await promise 返回的就是其结果。但是如果 promise 被 reject,它将 throw 这个 error,就像在这一行有一个 throw 语句那样。

async function f() {
  await Promise.reject(new Error("Whoops!"));
}

上面代码和下面的是一样的

async function f() {
  throw new Error("Whoops!");
}

我们可以用 try…catch 来捕获上面提到的那个 error,与常规的 throw 使用的是一样的方式:

async function f() {

  try {
    let response = await fetch('http://no-such-url');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();

总结:

函数前面的关键字 async 有两个作用:

  • 让这个函数总是返回一个 promise。
  • 允许在该函数内使用 await。

Promise 前的关键字 await 使 JavaScript 引擎等待该 promise settle,然后:

  • 如果有 error,就会抛出异常 —— 就像那里调用了 throw error 一样。
  • 否则,就返回结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值