欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

我的Promise秘密初探之小试牛刀

程序员文章站 2022-03-12 09:44:50
...

一、前言概述

在前端开发中,相信很多读者都使用过AJAX,这种比较???? 逼的异步处理方式,确实在一定程度上方便和简化了我们的某些需求,但有时候也会遇到在一个操作中,会需要多个异步请求的情况,在以往的处理中,比如笔者就曾做过2个及多个AJAX层层嵌套着处理的方式,这种方式,在当时看上去也可以满足一般的需求,但看着别扭,总觉得哪里不爽;

$.ajax({
    cache: false,
    type: 'POST',
    url: url1,
    dataType: 'json', 
    success: function (data) {
        $.ajax({
            cache: false,
            type: 'POST',
            url:url2,
            data: { para: list},
            dataType: 'json',
            success: function(result) {
                ......
            }
        })
    }
})
复制代码

如上,魔鬼嵌套;

很快,随着ES6的发布,Promise横空出世,之前多个AJAX多层嵌套的处理方式,看上去显得那么的low,如此的恶劣不堪,反观Promise,高端大气上档次-------哈哈,是不是有点喜新厌旧的嫌疑啊------瞬间,让我喜欢上了,有点一见钟情的赶脚????

整个就是一大方优雅的典范啊:

readFile(filename).then(function (data) {
    return data;
}).then(function (data) {
    return readFile(data);
}).then(function (data) {
    console.log(data);
}).catch(function(err){
    ......
});
复制代码

二、原理浅析

  1. Promise 名如其实,Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才做,例如网络请求、读取本地文件等;

    在这个过程中,Promise会经历三个状态:

  • Pending Promise对象实例创建时候的初始状态
  • Fulfilled 可以理解为成功的状态
  • Rejected 可以理解为失败的状态

then 方法就是用来指定Promise 对象的状态改变时确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)

  1. 示例分析:
let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        if(Math.random()>0.5)
            resolve('This is resolve!');
        else
            reject('This is reject!');
    }, 1000);
});
promise.then(Fulfilled,Rejected)
复制代码
  • 构造一个Promise实例需要给Promise构造函数传入一个函数。
  • 传入的函数需要有两个形参,两个形参都是function类型的参数。
    • 第一个形参运行后会让Promise实例处于resolve状态,所以我们一般给第一个形参命名为resolve,使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作
    • 第一个形参运行后会让Promise实例处于reject状态,所以我们一般给第一个形参命名为reject,将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作

三、小试牛刀

经过一些时间的学习和摸索,笔者在ES6自带的Promise的基础上,实现了对其all、race、resolve、reject的功能模拟;

  1. Promise.all
  • 参数:接受一个数组,数组内都是Promise实例。
  • 返回值:返回一个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中所有的实例都处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意一个实例处于reject状态,返回的Promise实例变为reject状态。
  • 代码如下
Promise.all = function(promises){
 return new Promise(function(resolve,reject){
   let done = gen(promises.length,resolve);
   for(let i=0;i<promises.length;i++){
     promises[i].then(function(data){
       done(i,data);
     },reject);
   }
 });
}
复制代码
  1. Promise.race
  • 参数:接受一个数组,数组内都是Promise实例
  • 返回值:返回一个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。当参数中任何一个实例处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意一个实例处于reject状态,返回的Promise实例变为reject状态。
  • 代码如下:
Promise.race = function(promises){
  return new Promise(function(resolve,reject){
    for(let i=0;i<promises.length;i++){
      promises[i].then(resolve,reject);
    }
  });
}
复制代码
  1. Promise.resolve
  • 该方法返回一个Promise实例,这个实例处于resolve状态。 会根据传递的参数不同而有不同的功能:
  • 当参数是值(对象、数组、字符串等)类型的:作为resolve传递出去的值;
  • 当参数是Promise实例:则原封不动返回;
  • 代码如下:
//返回一个立刻成功的promise
//但该方法,需要传入一个promise,但你只有一个普通的值,你就可以通过这个方法
//把这个普通的值(string number object)转成一个promise对象
Promise.resolve = function(value){
  return new Promise(function(resolve){
    resolve(value);
  });
}
复制代码
  1. Promise.reject
  • 该方法返回一个Promise实例,这个实例处于reject状态。
  • 参数一般就是抛出的错误信息。
  • 代码如下:
//返回一个立刻失败的promise
Promise.reject = function(reason){
  return new Promise(function(resolve,reject){
    reject(reason);
  });
}
复制代码

四、小结

以上就是在下对前端经常遇到的异步处理方式的前认与后知;本人自知才疏学浅,如果有一些理解的有失偏颇之处,欢迎各位随时拍砖与指正~!

当然,如果对您还有点作用的话,还望您评论鼓励,以资我继续前行,小可不胜感激~!