首页 web前端 js教程 前端 Promise 常见的一些应用场景

前端 Promise 常见的一些应用场景

Jun 15, 2020 am 10:08 AM
promise

本篇将结合自身使用 ES6 Promise的情况,总结下Promise在我们项目开发中的常见的应用场景,当然,Promise 也许不是唯一选项,但是我们作为一个合格的前端开发人员,我们有必要了解它。

Promise.all


语法:Promise.all(iterable)

参数:一个可迭代对象,如Array。

返回值:

  • 如果传递的iterable为空,则是已经解决的Promise。

Promise.all([]).then(res=>{
    console.log(res)//[]
})
登录后复制
  • 异步解析的Promise(如果传递的Iterable不包含Promise)。 请注意,在这种情况下,Google Chrome 58返回已解决的承诺。

Promise.all([1,2,3]).then(res=>{
    console.log(res)//[1,2,3]
})
登录后复制
  • 当给定可迭代对象中的所有promise已解决,或者任何promise均被拒绝时,此返回的promise将被异步解析/拒绝(堆栈为空时)

    1. 当给定可迭代对象中的所有promise 已解决

let promise1 = new Promise((resolve,reject)=>{
    resolve(1)
})
let promise2 = new Promise((resolve,reject)=>{
    resolve(2)
})

Promise.all([promise1,promise2,3]).then(res=>{
    console.log(res)//[1,2,3]
})
登录后复制

2..当给定可迭代对象中的任何promise被拒绝时

let promise1 = new Promise((resolve,reject)=>{
    resolve(1)
})
let promise2 = new Promise((resolve,reject)=>{
    reject(2)
})

Promise.all([promise1,promise2,3]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)//2
})
登录后复制

描述:

此方法对于汇总多个promise的结果很有用, 在ES6中可以将多个Promise.all异步请求并行操作:

1.当所有结果成功返回时按照请求顺序返回成功;

2.当其中有一个失败方法时,则进入失败方法;

应用场景1:多个请求结果合并在一起

具体描述:一个页面,有多个请求,我们需求所有的请求都返回数据后再一起处理渲染

思考:如果并发请求的话,每个请求的loading状态要单独设置,多个的话可能多个loading 重合,页面显示的内容 根据请求返回数据的快慢 有所差异,具体表现在渲染的过程,为提升用户体验,我们可以采用 所有请求返回数据后,再一起渲染,此时我们关闭请求的单独loading设置,通过Promise.all 汇总请求结果,从开始到结束,我们只设置一个 loading 即可。

//1.获取轮播数据列表
function getBannerList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('轮播数据')
        },300)
    })
}

//2.获取店铺列表
function getStoreList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('店铺数据')
        },500)
    })
}

//3.获取分类列表
function getCategoryList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('分类数据')
        },700)
    })
}

function initLoad(){
    // loading.show() //加载loading
    Promise.all([getBannerList(),getStoreList(),getCategoryList()]).then(res=>{
        console.log(res)
        // loading.hide() //关闭loading
    }).catch(err=>{
        console.log(err)
        // loading.hide()//关闭loading
    })
}
//数据初始化    
initLoad()
登录后复制

应用场景2:合并请求结果并处理错误

描述:我们需求单独处理一个请求的数据渲染和错误处理逻辑,有多个请求,我们就需要在多个地方写

思考:我们能否把多个请求合并在一起,哪怕有的请求失败了,也返回给我们,我们只需要在一个地方处理这些数据和错误的逻辑即可。

//1.获取轮播图数据列表
function getBannerList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            // resolve('轮播图数据')
            reject('获取轮播图数据失败啦')
        },300)
    })
}

//2.获取店铺列表
function getStoreList(){
   return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('店铺数据')
        },500)
    })
}

//3.获取分类列表
function getCategoryList(){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('分类数据')
        },700)
    })
}

function initLoad(){
    // loading.show()
    Promise.all([
        getBannerList().catch(err=>err),
        getStoreList().catch(err=>err),
        getCategoryList().catch(err=>err)
    ]).then(res=>{
        console.log(res) // ["获取轮播图数据失败啦", "店铺数据", "分类数据"]
        
        if(res[0] == '轮播图数据'){
            //渲染
        }else{
            //获取 轮播图数据 失败的逻辑
        }
        if(res[1] == '店铺数据'){
            //渲染
        }else{
            //获取 店铺列表数据 失败的逻辑
        }
        if(res[2] == '分类数据'){
            //渲染
        }else{
             //获取 分类列表数据 失败的逻辑
        }
        
        // loading.hide()
    })
}

initLoad()
登录后复制

有时候页面挂掉了,可能因为接口异常导致,或许只是一个无关紧要的接口挂掉了。那么一个接口挂掉了为什么会导致整个页面无数据呢?Promise.all告诉我们,如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),就不再执行then方法回调,以上用例 正好可以解决此种问题

应用场景3:验证多个请求结果是否都是满足条件

描述:在一个微信小程序项目中,做一个表单的输入内容安全验证,调用的是云函数写的方法,表单有多7个字段需要验证,都是调用的一个 内容安全校验接口,全部验证通过则 可以 进行正常的提交

function verify1(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },200)
    })
}

function verify2(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },700)
    })
}

function verify3(content){
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve(true)
        },300)
    })
}



Promise.all([verify1('校验字段1的内容'),verify2('校验字段2的内容'),verify3('校验字段3的内容')]).then(result=>{
    console.log(result)//[true, true, true]

    let verifyResult = result.every(item=>item)
    //验证结果
    console.log(verifyResult?'通过验证':'未通过验证')// 通过验证
}).catch(err=>{
    console.log(err)
})
登录后复制

Promise.race


语法:Promise.race(iterable)

参数: iterable 可迭代的对象,例如Array。可迭代的。

返回值:Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝

描述 race 函数返回一个 Promise,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。

如果传的迭代是空的,则返回的 promise 将永远等待。

如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺,则 Promise.race 将解析为迭代中找到的第一个值。

应用场景1:图片请求超时

//请求某个图片资源
function requestImg(){
    var p = new Promise(function(resolve, reject){
        var img = new Image();
        img.onload = function(){
           resolve(img);
        }
        //img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg"; 正确的
        img.src = "https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1";
    });
    return p;
}

//延时函数,用于给请求计时
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('图片请求超时');
        }, 5000);
    });
    return p;
}

Promise
.race([requestImg(), timeout()])
.then(function(results){
    console.log(results);
})
.catch(function(reason){
    console.log(reason);
});
登录后复制

应用场景2:请求超时提示

描述:有些时候,我们前一秒刷着新闻,下一秒进入电梯后,手机页面上就会提示你 “网络不佳”

//请求
function request(){
    return new Promise(function(resolve, reject){
       setTimeout(()=>{
            resolve('请求成功')
       },4000)
    })
}

//请求超时提醒
function timeout(){
    var p = new Promise(function(resolve, reject){
        setTimeout(function(){
            reject('网络不佳');
        }, 3000);
    });
    return p;
}



Promise.race([
    request(),
    timeout()
])
.then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err)//网络不佳
})
登录后复制

Promise.prototype.then


应用场景1:下个请求依赖上个请求的结果

描述:类似微信小程序的登录,首先需要 执行微信小程序的 登录 wx.login 返回了code,然后调用后端写的登录接口,传入 code ,然后返回 token ,然后每次的请求都必须携带 token,即下一次的请求依赖上一次请求返回的数据

function A(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('B依赖的数据')
        },300)
    })
}
function B(prams){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(prams + 'C依赖的数据')
        },500)
    })
}
function C(prams){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(prams)
        },1000)
    })
}

//我们期望的是走 try ,由于A B C模拟的请求中都是没有reject,用 try catch 捕获错误
try{
    A().then( res=>B(res) ).then( res=>C(res) ).then( res=>{
        console.log(res)//B依赖的数据C依赖的数据
    })   
} catch(e){
    
}
登录后复制

应用场景2:中间件功能使用

描述:接口返回的数据量比较大,在一个then 里面处理 显得臃肿,多个渲染数据分别给个then,让其各司其职

//模拟后端返回的数据

let result = {
    bannerList:[
        {img:'轮播图地址'}
    //...
    ],
    storeList:[
        {name:'店铺列表'}
    //...
    ],
    categoryList:[
        {name:'分类列表'}
    //...
    ],
    //...
}

function getInfo(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(result)
        },500)
    })
}

getInfo().then(res=>{

    let { bannerList } = res
    //渲染轮播图
    console.log(bannerList)
    return res
}).then(res=>{
    
    let { storeList } = res
    //渲染店铺列表
    console.log(storeList)
    return res
}).then(res=>{
    let { categoryList } = res
    console.log(categoryList)
    //渲染分类列表
    
    return res
})
登录后复制

推荐教程:《JS教程

以上是前端 Promise 常见的一些应用场景的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

言出必行:兑现承诺的好处和坏处 言出必行:兑现承诺的好处和坏处 Feb 18, 2024 pm 08:06 PM

在日常生活中,我们常常会遇到承诺与兑现之间的问题。无论是在个人关系中,还是在商业交易中,承诺的兑现都是建立信任的关键。然而,承诺的利与弊也常常会引起争议。本文将探讨承诺的利与弊,并给出一些建议,如何做到言出必行。承诺的利是显而易见的。首先,承诺可以建立信任。当一个人信守承诺时,他会让别人相信自己是一个可信赖的人。信任是人与人之间建立起的纽带,它可以让人们更加

在Vue应用中遇到Uncaught (in promise) TypeError怎么办? 在Vue应用中遇到Uncaught (in promise) TypeError怎么办? Jun 25, 2023 pm 06:39 PM

Vue是一款流行的前端框架,在开发应用时经常会遇到各种各样的错误和问题。其中,Uncaught(inpromise)TypeError是常见的一种错误类型。在本篇文章中,我们将探讨它的产生原因和解决方法。什么是Uncaught(inpromise)TypeError?Uncaught(inpromise)TypeError错误通常出现在

深入了解Promise.resolve() 深入了解Promise.resolve() Feb 18, 2024 pm 07:13 PM

Promise.resolve()详解,需要具体代码示例Promise是JavaScript中一种用于处理异步操作的机制。在实际开发中,经常需要处理一些需要按顺序执行的异步任务,而Promise.resolve()方法就是用来返回一个已经Fulfilled状态的Promise对象。Promise.resolve()是Promise类的一个静态方法,它接受一个

实例解析ES6 Promise的原理和使用 实例解析ES6 Promise的原理和使用 Aug 09, 2022 pm 03:49 PM

利用Promise对象,把普通函数改成返回Promise的形式,解决回调地狱的问题。明白Promise的成功失败调用逻辑,可以灵活的进行调整。理解核心知识,先用起来,慢慢整合吸收知识。

哪些浏览器支持Promise? 哪些浏览器支持Promise? Feb 19, 2024 pm 04:41 PM

浏览器兼容性:哪些浏览器能够支持Promise?随着Web应用程序的复杂性不断提高,开发人员们迫切需要解决JavaScript中的异步编程问题。过去,开发人员通常使用回调函数来处理异步操作,但这会导致代码复杂和难以维护。为了解决这个问题,ECMAScript6引入了Promise,它提供了一种更直观、更灵活的处理异步操作的方式。Promise是一种用于处理异

promise对象有哪些 promise对象有哪些 Nov 01, 2023 am 10:05 AM

promise对象状态有:1、pending:初始状态,既不是成功,也不是失败状态;2、fulfilled:意味着操作成功完成;3、rejected:意味着操作失败。一个Promise对象一旦完成,就会从pending状态变为fulfilled或rejected状态,且不能再改变。Promise对象在JavaScript中被广泛使用,以处理如AJAX请求、定时操作等异步操作。

PHP 函数返回 Promise 对象有什么优势? PHP 函数返回 Promise 对象有什么优势? Apr 19, 2024 pm 05:03 PM

优势:异步和非阻塞,不阻塞主线程;提高代码可读性和可维护性;内置错误处理机制。

promise什么意思 promise什么意思 Nov 02, 2023 pm 05:30 PM

Promise是一种用于处理异步操作的编程模式,它是一种代表了异步操作最终完成或失败的对象,可以看作是对异步操作的一种承诺,它可以更好地管理和组织异步代码,使得代码更加可读性高、可维护性强。Promise对象有三个状态:pending、fulfilled和rejected。Promise的核心思想是将异步操作从回调函数中分离出来,通过链式调用的方式来表达异步操作之间的依赖关系。

See all articles