首页 > 其他分享 >promise(千锋)

promise(千锋)

时间:2024-01-18 23:02:00浏览次数:25  
标签:千锋 resolve err res Promise result reject promise

目录

Promise

作者:kerwin

版本:QF1.0

版权:千锋HTML5大前端教研院

公众号: 大前端私房菜

一. Promise是什么?

Promise 是异步编程的一种解决方案,比传统的解决方案回调函数, 更合理和更强大。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象 。

  • 指定回调函数方式更灵活易懂。
  • 解决异步 回调地狱 的问题。
1. 回调地狱
  • 当一个回调函数嵌套一个回调函数的时候

  • 就会出现一个嵌套结构

  • 当嵌套的多了就会出现回调地狱的情况

  • 比如我们发送三个 ajax 请求

    • 第一个正常发送
    • 第二个请求需要第一个请求的结果中的某一个值作为参数
    • 第三个请求需要第二个请求的结果中的某一个值作为参数
    ajax({
      url: '我是第一个请求',
      success (res) {
        // 现在发送第二个请求
        ajax({
          url: '我是第二个请求',
          data: { a: res.a, b: res.b },
          success (res2) {
            // 进行第三个请求
            ajax({
              url: '我是第三个请求',
              data: { a: res2.a, b: res2.b },
      				success (res3) { 
                console.log(res3) 
              }
            })
          }
        })
      }
    })
    
  • 回调地狱,其实就是回调函数嵌套过多导致的

  • 当代码成为这个结构以后,已经没有维护的可能了
    原生js回调地狱
    原生回调写死回调时间,省市区的设计无法知道回调时间
    run(0)
    setTimeout(() => {
    	run(1)
    	setTimeout(() => {
    		run(2)
    		setTimeout(() => {
    			run(3)
    		},2000)
    	},2000)
    },2000)
    

二. Promise使用

  • 语法:

    new Promise(function (resolve, reject) {
      // resolve 表示成功的回调
      // reject 表示失败的回调
    }).then(function (res) {
      // 成功的函数
    }).catch(function (err) {
      // 失败的函数
    })
    

三. Promise 对象的状态

Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

异步操作未完成(pending)
异步操作成功(fulfilled)
异步操作失败(rejected)

这三种的状态的变化途径只有两种。

从“未完成”到“成功”
从“未完成”到“失败”

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。

因此,Promise 的最终结果只有两种。

异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。

image-20220902141409899

四.Promise对象方法

Promise 是一个对象,也是一个构造函数。

1.Promise.resolve

将现有对象转为 Promise 对象

Promise.resolve('kerwin')
// 等价于
new Promise(resolve => resolve('kerwin'))
2.Promise.reject

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为 rejected

const p = Promise.reject('error');
// 等同于
const p = new Promise((resolve, reject) => reject('error'))
3.Promise.all

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

p的状态由p1,p2,p3 决定,分成两种情况。

(1)只有 p1p2p3的状态都变成 fulfilledp的状态才会变成 fulfilled,此时 p1p2p3的返回值组成一个数组,传递给 p的回调函数。

(2)只要 p1p2p3之中有一个被 rejectedp的状态就变成 rejected,此时第一个被 reject的实例的返回值,会传递给 p的回调函数。

4.Promise.race

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要 p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给 p的回调函数。

5.Promise.allSettled

Promise.allSettled()方法,用来确定一组异步操作是否都结束了(不管成功或失败)。所以,它的名字叫做”Settled“,包含了”fulfilled“和”rejected“两种情况。

const promises = [ ajax('/200接口'), ajax('/401接口') ];

Promise.allSettled(promises).then(results=>{
    // 过滤出成功的请求
    results.filter(item =>item.status === 'fulfilled');
    过滤出失败的请求
    results.filter(item=> item.status === 'rejected');
})

6.Promise.any

只要参数实例有一个变成 fulfilled状态,包装实例就会变成 fulfilled状态;如果所有参数实例都变成 rejected状态,包装实例就会变成 rejected状态。

Promise.any()Promise.race()方法很像,只有一点不同,就是 Promise.any()不会因为某个 Promise 变成 rejected状态而结束,必须等到所有参数 Promise 变成 rejected状态才会结束。

五.手写Promise

	//*
 * @作者: kerwin
 */
function KerwinPromise(executor) {
    this.status = "pending";
    this.result = undefined;
    this.cb = []
    var _this = this;

    function resolve(res) {
        if (_this.status !== "pending") return;  //判断状态,由于不可变,
        // console.log(_this)
        _this.status = "fulfilled"
        _this.result = res;

        _this.cb.forEach(item => {
            item.successCB && item.successCB(_this.result)
        });
    }

    function reject(res) {
        if (_this.status !== "pending") return;
        // console.log("reject")
        _this.status = "rejected"
        _this.result = res;
        _this.cb.forEach(item => {
            item.failCB && item.failCB(_this.result)
        });
    }
    executor(resolve, reject)
}

KerwinPromise.prototype.then = function (successCB, failCB) {

    if(!successCB){
        successCB = value=>value
    }
    if(!failCB){
        failCB = error=>error
    }

    // successCB()
    return new KerwinPromise((resolve, reject) => {
        if (this.status === "fulfilled") {
            var result = successCB && successCB(this.result)
            // console.log(result);

            if (result instanceof KerwinPromise) {
                result.then(res => {
                    // console.log(res)
                    resolve(res);
                }, err => {
                    // console.log(err)
                    reject(err)
                })
            } else {
                resolve(result);
            }
        }
        if (this.status === "rejected") {
            var result = failCB && failCB(this.result)

            if (result instanceof KerwinPromise) {
                result.then(res => {
                    // console.log(res)
                    resolve(res);
                }, err => {
                    // console.log(err)
                    reject(err)
                })
            } else {
                reject(result);
            }
        }

        if (this.status === "pending") {
            //收集回调
            this.cb.push({
                successCB: () => {
                    var result = successCB && successCB(this.result)

                    if (result instanceof KerwinPromise) {
                        result.then(res => {
                            // console.log(res)
                            resolve(res);
                        }, err => {
                            // console.log(err)
                            reject(err)
                        })
                    } else {
                        resolve(result);
                    }
                },
                failCB: () => {
                    var result = failCB && failCB(this.result)
                    if (result instanceof KerwinPromise) {
                        result.then(res => {
                            // console.log(res)
                            resolve(res);
                        }, err => {
                            // console.log(err)
                            reject(err)
                        })
                    } else {
                        reject(result);
                    }
                }
            })
        }
    })
}

KerwinPromise.prototype.catch= function(failCB){
    this.then(undefined,failCB)
}

六.Async与Await

1.Async

async 函数,使得异步操作变得更加方便。

  • 更好的语义。
  • 返回值是 Promise。
async function test(){

}
test()
2.Await

await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

async function test(){
    var res1 =  await ajax("http://localhost:3000/news1")
    var res2 =  await ajax("http://localhost:3000/news2")
    return res2
}

test().then(res=>{
	console.log("返回结果",res)
}).catch(err=>{
	console.log("err",err)
})
3.错误处理
try{
    var res1 =  await ajax("http://localhost:3000/news1")
    var res2 =  await ajax("http://localhost:3000/news2")
}catch(err){
	console.log("err",err)
}

标签:千锋,resolve,err,res,Promise,result,reject,promise
From: https://www.cnblogs.com/SanshQ/p/17973624

相关文章

  • React(千锋)
    目录React18新增特性一.React18介绍1.新的项目创建2.老的项目升级二.RenderAPI三.自动批量更新State1.setTimeout2.promise3.原生事件4.flushSync四.ConcurrentMode(并发模式)1.useTransition2.useDeferredValue五.严格模式(mutedcolors)六.Suspense组件的变化1.版本......
  • Git(千锋)
    目录Git一.走入Git1.Git介绍2.Git对比SVN3.Git安装二.Git常用命令1.设置用户签名2.初始化本地库3.Git工作区、暂存区和版本库4.gitadd5.gitcommit6.gitrevert与gitreset三.Git分支1.初识分支2.创建分支3.切换分支4.合并分支5.删除分支四.远程仓库1.创建一个远程仓库2.添......
  • Node.js(千锋)
    目录Node.js(最全)基础+全栈项目一、Node.js基础1.认识Node.js01nodejs的特性02使用Node.js需要了解多少JavaScript03浏览器环境vsnode环境2.开发环境搭建3.模块、包、commonJS02CommonJS规范03modules模块化规范写法4.Npm&Yarn01npm的使用02全局安装nrm03yar......
  • 在nodejs环境使用promise函数
     如果单纯的使用promise,对环境比较简单,只需要一个js文件即可。//constp1=newPromise((resolve,reject)=>{//setTimeout(()=>{//resolve('resolve')//},1000)//})//constp2=newPromise((resolve,reject)=>{//setTimeout(()......
  • Promise超详细源码解读
    说到promise,相信大家在日常开发中都经常使用到,它是我们异步操作中必不可少的一部分,可以让代码看起来变得更好理解;我曾在技术社区看过许多关于promise底层原理的文章,大概原理明白,这次,我准备系统的分析实现源码并记录下来,本文将一行行代码去分析最后附加流程图和总结,希望这能对你......
  • JavaScript Promise超详细源码解读
    Promise超详细源码解读说到promise,相信大家在日常开发中都经常使用到,它是我们异步操作中必不可少的一部分,可以让代码看起来变得更好理解;我曾在技术社区看过许多关于promise底层原理的文章,大概原理明白,这次,我准备系统的分析实现源码并记录下来,本文将一行行代码去分析最后附加流程图......
  • 8 个关于 Promise 的高级用途的技巧
    我发现很多人只知道如何常规地使用promise。在js项目中,promise的使用应该是必不可少的,但我发现在同事和面试官中,很多中级以上的前端仍然坚持promiseInst.then()、promiseInst.catch()、Promise等常规用法等等。即使是async/await他们也只知道它但不知道为什么要使用它。但实际上,P......
  • 动态添加的Promise按顺序执行
    原文链接:https://www.cnblogs.com/yalong/p/17935043.html动态添加的Promise异步事件按顺序执行需求描述用户点击一次页面上的一个按钮,就播放一个动画,如果点击n次就触发n次动画;在播放动画的同时,如果再点击按钮,那么会把n的次数累加,动画播放也增加对应的次数;同时支持在动画队......
  • 除了Promise.all(),使用Promise.allSettled()方式请求,避免使用循环请求
    constgetFilePromises:Promise<any>[]=[];fileIds.forEach((item)=>{getFilePromises.push(getFileInfoApi({id:item}));});Promise.allSettled(getFilePromises).then((res)=>{this.fileList=res.map((item,index)=>......
  • Promise 和 Async/Await 到底有啥区别?
    在JavaScript中,promise和async/await是处理异步操作的两种不同方式。但它们是密切相关的。 promise是最终导致异步操作完成或失败的对象。承诺可以处于以下三种状态之一:挂起、已履行或拒绝。异步操作完成后,承诺要么以值实现,要么因错误而被拒绝。 //UsingPromisesfu......