前端学习9 Promise

promise,是异步操作(读取文件,发起网络请求)的一种解决方案,解决了回调地狱(传统的解决方案)的出现。

1.回调地狱

在异步编程的领域中,回调地狱是一个经常困扰开发者的难题。它的产生源于回调函数的过度嵌套,从而导致代码结构变得错综复杂。当一个回调函数内部嵌套另一个回调函数时,就像是在一个盒子里不断嵌套更小的盒子,层层深入。

例如,假设我们要模拟发送三个异步请求,并且第二个请求依赖于第一个请求结果中的某个特定值作为参数,第三个请求又依赖于第二个请求结果中的某个值作为参数。如果使用传统的回调函数方式,代码可能会呈现出如下的形态:

 function fn() {
 
        setTimeout(function () {
 
            console.log("111");
 
            setTimeout(function () {
 
                console.log("222");
 
                setTimeout(function () {
 
                    console.log("333");
 
                }, 1000);
 
            }, 2000);
 
        }, 3000);
 
    }
 
    fn();

在这段代码中,setTimeout函数模拟了异步操作,锁着嵌套函数的一层层增加,代码就像一团乱麻,所以我们使用Promise来解决回调地狱这个问题,之后我们会学习最先进的异步方案:async 和 await。

2. promise 对象

Promise对象是一个独立的个体,通过自身的状态来控制异步操作。promise一共有三种状态,每一种状态都代表着异步操作的一个特定阶段:

1.pedding :进行中,Promise处于等待;

2.fulfilled :异步操作已经成功;

3.rejected :异步操作已经失败;

3. Promise 实例

const ps = new Promise(function (resolve,reject) {});

这样就创建了一个Promise实例,Promise接受一个函数类型作为参数,这个函数有接受两个参数resolve,reject。分别表示成功回调(fulfilled)和失败回调(rejected)。

4.Promise 方法

为了更好的控制下一步执行,我们有三个实例方法:then,catch,finally;

4.1 then 方法

then方法一般接受两个参数resolve,reject。

const ps2 = new Promise(function (resolve, reject) {
  let number = 9;
  if (number >= 10) {
    resolve(number);
  } else {
    reject("number 小于10");
  }
});
 
ps2.then(
  function (res) {
  console.log(res);
  },
  function (err) {
    console.log(err);
  }
);

4.2 catch 方法

then方法支持链式调用,但是then的执行严重依赖上一步的结果,上一步没有结果,那么下一步就不会执行,但是每一步都写reject特别麻烦,所以诞生了catch,then就可以省略reject方法,reject交给catch执行,同时catch还可以捕获resolve的异常

const ps2 = new Promise(function (resolve, reject) {
  let number = 9;
  if (number >= 10) {
    resolve(number);
  } else {
    reject("number 小于10");
  }
});
 
ps2
  .then(function (res) {})
  .catch(function (err) {
    console.log(err);
  });

4.3 finally 方法

无论成功还是失败都需要执行一些操作,就诞生了 finally。我们可以在这做一些清理工作。

const ps2 = new Promise(function (resolve, reject) {
  let number = 9;
  if (number >= 10) {
    resolve(number);
  } else {
    reject("number 小于10");
  }
});
 
ps2
  .then(function (res) {})
  .catch(function (err) {
    console.log(err);
  })
  .finally(function () {
    console.log("end");
  });

5.then的链式调用

then方法返回的是一个新的Promise实例,也就是promise能链式书写的原因。

const ps = new Promise(function (resolve, reject) {
  let number = 10;
  if (number >= 10) {
    resolve(number);
  } else {
    reject("number 小于10");
  }
});
 
ps.then(function (res) {
  return res * 10;
})
  .then(function (res) {
    return res + 2;
  })
  .then(function (res) {
    if (res > 100) {
      console.log(res);
    } else {
      console.log("最后结果小于100");
    }
  });

其中return res * 10;创建一个新的Promise,其状态为fulfilled,并携带结果值 100。 我们来可以返回一个自己创建的Promise对象。

function date() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('相亲了');
            // 可以传递一个对象表示相亲的结果
            resolve('和最爱的人相亲了');
        }, 2000);
    });
}

function marry() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('结婚了');
            // 传递结婚的相关信息
            resolve('和最爱的人结婚了');
        }, 1000);
    });
}

function baby() {
    console.log('出生了');
}

date()
    .then(resultFromDate => {
        console.log('相亲结果:', resultFromDate);
        return marry();
    })
    .then(resultFromMarry => {
        console.log('结婚信息:', resultFromMarry);
        baby();
    });

5.Promise 原型方法

为了满足更多的业务需要,又诞生了 6 个原型方法 Promise.all()、Promise.allSettled()、Promise.any()、Promise.race()、Promise.reject()、Promise.resolve()。且都会返回一个确定状态的 Promsie 对象。

5.1 Promise.all()

通过数组的形式传入异步操作,所有的异步执行都成功,才执行成功,如果有一个失败了,就执行失败。

Promise.all([ps1, ps2])
  .then(function (res) {
    console.log("都成功", res);
  })
  .catch(function (err) {
    console.log(err);
  });

5.2 Promise.allSettled()

所有执行都有结果了就执行,无论成功还是失败。

Promise.allSettled([ps1, ps2, ps3, ps4]).then(function (res) {
  console.log("都返回结果", res);
});

5.3 Promise.any()

任意异步成功了就执行。

Promise.any([ps1, ps2, ps3, ps4]).then(function (res) {
  console.log("任意成功", res);
});

5.4 Promise.race()

任意异步成功或失败就执行。

5.5 Promise.reject()

返回一个状态为 rejected 的 Promise 对象。

5.6 Promise.resolve()

会接收 4 种类型的参数:promise 实例 、具有 then 方法的对象、没有 then 方法的对象、不传参

当参数是一个 Promise 实例时,直接返回这个实例。

Promise.resolve(ps1);

当参数是一个具有 then 方法的对象时,将这个对象转为 Promise 对象,并立即执行对象的 then 方法

let obj = {
  name: "yqcoder",
  then(resolve) {
    resolve(this.name);
  },
};
 
Promise.resolve(obj);

当参数是一个没有 then 方法的对象,或者参数不是对象时,就会返回状态为 fulfilled 的新的 Promise 对象,并将参数传入下一个 then。

let obj = {
  name: "yqcoder",
};
 
let ps = Promise.resolve(obj);
 
ps.then(function (res) {
  console.log("结果", res);
});

当不带任何参数时,就会返回一个状态为 fulfilled 的 Promise 对象

Promise.resolve();
#前端学习#
全部评论
选前端可算选对了
点赞 回复 分享
发布于 04-08 23:40 湖北

相关推荐

评论
2
2
分享

创作者周榜

更多
牛客网
牛客企业服务