Promise总结

一、Promise对象

       一个Promise对象就是一个异步操作,包含三个状态,pending,resolve,rejected,状态的改变只能从pending到resolve或pending到rejected(状态一旦修改就不能在改变)。在Event Loop中属于微任务。

二、实例方法:

then 调用then如果有返回值,返回的是一个新的Promise实例,隐藏可以使用链式写法,继续then下去。(then里面传递的函数会被置入一个微任务队列,当事件队列清空后才会执行)
       catch 异常捕获

三、静态方法:

        all 将多个Promise实例转换成一个Promise实例,如果不是则先调用resolve将参数转换成Promise实例,所有的状态都变成Fulfilled,才会返回给回调,但是有一个Rejected就会返回
        race 和all一样,区分在返回值,有一个状态改变,就会返回给回调。
        resolve 返回一个解析过的Promise对象。参数分几种情况,1种是参数为Promise对象,此时直接返回,如果是字符串、函数等会转换成Parmise对象且状态为Fulfilled,并且有then属性。最后有可能是一个带有then属性的对象,立即执行then

                并更改状态为Fulfilled。
        reject  将对象转成Promise对象 且状态为Rejected
        附加方法
        done   捕获最后执行可能出现的错误
        finally 最后必须执行的函数,接收参数为回调。

四、链式调用:

基于Promise实现链式调用,要求下一次的任务依赖上游的数据(rxjs concat操作符)

/**
 * 一、Promise 链式调用实现
 * @returns {Promise<any>}
 */
function fn() {
  return new Promise((resolve, reject) => {
      setTimeout(()=> {
        resolve('fn');
      }, 1000);
  });
}

function fn1(res) {
  return new Promise((resolve, reject) => {
    setTimeout(()=> {
      resolve(res)
    }, 1000);
  });
}

function fn2(res) {
  return new Promise((resolve, reject) => {
    setTimeout(()=> {
      resolve(res)
    }, 1000);
  });
}

function fn3(res) {
  return new Promise((resolve, reject) => {
    setTimeout(()=> {
      resolve(res)
    }, 1000);
  });
}

fn().then((res) => {
  console.log(res)
  return fn1(res + 1);
})
  .then((res) => {
    console.log(res)
    return fn2(res + 1);
  })
  .then((res) => {
    console.log(res)
    return fn3(res + 1);
  });


/**
 * 使用async实现
 * @returns {Promise.<void>}
 */
async function getData() {
    const upstream = await fn();
    await fn1();
    await fn2();
    // ...
}
/**
 * 使用reduce实现
 * @returns Promise<void>
 */
[fn, fn1, fn2,fn3].reduce(
		// @ts-ignore
		(prev, current) => prev.then((res) => current(res)),
		Promise.resolve(initialValue)
	)

五、API尝试实现:

function _Promise(fn) {
    const me = this;
    // 默认状态
    me.status = 'pending';
    // 保存成功数据
    me.data = null;
    //失败信息保存
    me.errData = null;
    // 成功回调 获取then里面成功的回调函数
    me.onResolveCallbacks = [];
    // 失败回调 获取then里面失败的回调函数
    me.onRejectedCallbacks = [];

    // 成功函数
    function resolve(data) {
        if (me.status === 'pending') {
            me.status = 'fulfilled';
            me.data = data;
            me.onResolveCallbacks.forEach((item) => {
                item(me.data);
            })
        }
    }

    /**
     * 失败处理函数
     * @param data
     */
    function reject(data) {
        if (me.status === 'pending') {
            me.status = 'rejected';
            me.errData = data;
            me.onRejectedCallbacks.forEach((item) => {
                item(me.errData);
            })
        }
    }

    // 执行函数
    try {
        fn(resolve, reject);
    } catch (err) {
        reject(err)
    }
}

_Promise.prototype.then = function (resolve, reject) {
    const me = this;
    const _setPromise = (_P, _resolve, _reject) => {
        // then返回值如果是_Promise类型 则执行then处理
        if (_P instanceof _Promise) {
            _P.then(_resolve, _reject)
        } else {
            _resolve(_P)
        }
    };
    // 如果状态为成功 执行resolve
    if (me.status === 'fulfilled') {
        return new _Promise((_resolve, _reject) => {
            const _P = resolve(me.data);
            // 如果then函数的返回值是个_Promise 则执行_Promise.then函数
            // 否则将执行结果返回
            _setPromise(_P, _resolve, _reject);
        });
    }
    // 如果状态为成功 执行resolve
    if (me.status === 'rejected') {
        return new _Promise((_resolve, _reject) => {
            const _P = reject(me.errData);
            _setPromise(_P, _resolve, _reject);
        });
    }
    if (me.status === 'pending') {
        return new Promise((_resolve, _reject) => {
            me.onResolveCallbacks.push(() => {
                const _P = resolve(me.data);
                _setPromise(_P, _resolve, _reject);
            });
            me.onRejectedCallbacks.push(() => {
                const _P = reject(me.errData);
                _setPromise(_P, _resolve, _reject);
            });
        });
    }
}

_Promise.prototype.catch = function (fn) {
    return this.then(null, fn);
}


_Promise.all = function (iterables) {
    return new _Promise((resolve, reject) => {
        // 数据拼接
        let data = [];
        // 便利次数
        let index = 0;
        // 范围信息次数
        let resIndex = 0;
        for (let P of iterables) {
            // 防止乱序 获取then的正确顺序
            const dataIndex = index;
            P.then((res) => {
                // 保存信息
                data[dataIndex] = res;
                resIndex++;
                if (resIndex === data.length) {
                    resolve(data);
                }
            }, (err) => {
                reject(err);
            });
            index++;
        }
        if (!index) resolve([]);
    });
};

// 测试
new _Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2222)
    }, 1000)
}).then((res) => {
    console.log(res)
    return new _Promise((_resolve, reject) => {
        setTimeout(() => {
            _resolve(4444)
        }, 1000);
    });
}).then((res) => {
    console.log(res)
})


new _Promise((resolve, reject) => {
    resolve(2222)
}).then((res) => {
    console.log(res)
    return new _Promise((_resolve, reject) => {
        _resolve(4444)
    });
}).then((res) => {
    console.log(res)
})

_Promise.all([new _Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2222)
    }, 1000)
}), new _Promise((resolve, reject) => {
    resolve(4444)
})]).then((res)=> {
    console.log(res)
});
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Promise是一种用于处理异步操作的JavaScript对象。它的原理是基于事件循环和回调函数的机制。当我们创建一个Promise实例时,它会立即执行一个传入的函数,并返回一个Promise对象。这个函数又被称为executor函数,它接受两个参数resolve和reject。resolve函数用于将Promise的状态从pending变为fulfilled,并传递一个值作为结果;reject函数用于将Promise的状态从pending变为rejected,并传递一个原因作为错误信息。 在executor函数中,我们可以通过调用resolve和reject来改变Promise的状态。当某个异步操作成功完成时,我们可以调用resolve来将Promise状态变为fulfilled,并传递异步操作的结果。而当某个异步操作失败时,我们可以调用reject来将Promise状态变为rejected,并传递一个错误原因。 Promise的优点之一是可以链式调用。通过在Promise对象上调用then方法,我们可以注册回调函数来处理Promise的结果。当Promise的状态从pending变为fulfilled时,将会执行与then方法关联的回调函数,并将Promise的结果作为参数传递给回调函数。当Promise的状态从pending变为rejected时,将会执行与catch方法关联的回调函数,并将错误原因作为参数传递给回调函数。通过链式调用then方法,我们可以将多个异步操作串联起来,形成一个异步操作的流水线。 总结起来,Promise的原理是通过executor函数、resolve函数和reject函数来实现异步操作的封装和处理。通过链式调用then方法,可以对Promise的结果进行处理和传递。而Promise的状态变化是基于事件循环和回调函数的机制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [这一次,彻底弄懂 Promise 原理](https://blog.csdn.net/weixin_30881367/article/details/101419505)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值