ホームページ  >  記事  >  ウェブフロントエンド  >  フロントエンド Promise のいくつかの一般的なアプリケーション シナリオ

フロントエンド Promise のいくつかの一般的なアプリケーション シナリオ

hzc
hzc転載
2020-06-15 10:08:314312ブラウズ

この記事では、私自身の ES6 Promise の使用法に基づいて、プロジェクト開発における Promise の一般的なアプリケーション シナリオを要約します。もちろん、Promise が唯一の選択肢ではないかもしれませんが、資格のあるフロントエンド開発者として、次のことを理解する必要があります。それ。

Promise.all


## 構文: Promise.all (反復可能)

パラメータ: 配列などの反復可能なオブジェクト。

戻り値:

  • 渡された反復可能オブジェクトが空の場合、それは解決された Promise です。


  • Promise.all([]).then(res=>{
        console.log(res)//[]
    })
  • Promise は非同期的に解決されます (渡された Iterable に Promise が含まれていない場合)。この場合、Google Chrome 58 は解決された Promise を返すことに注意してください。

  • Promise.all([1,2,3]).then(res=>{
        console.log(res)//[1,2,3]
    })
  • この返された Promise は、指定された反復可能オブジェクト内のすべての Promise が解決されたとき、またはいずれかの Promise が拒否されたとき (スタックがempty)

    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 が解決されたとき いずれかの 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 : 複数のリクエスト結果

#詳細な説明: 1 つのページに複数のリクエストがあります。一緒に処理してレンダリングする前に、すべてのリクエストがデータを返す必要があります。

考え:同時リクエストの場合、各リクエストの読み込みステータスを個別に設定する必要があります。複数の読み込みがある場合、複数の読み込みが重なる可能性があります。ページに表示されるコンテンツは、リクエストに応じてデータが返される速度に応じて変化し、それが具体的に反映されますレンダリング プロセス。ユーザー エクスペリエンスを向上させるために、すべてのリクエストを使用してデータを返し、それらをまとめてレンダリングできます。このとき、リクエストの個別読み込み設定をオフにし、Promise.all を通じてリクエスト結果を要約します。最初から最後まで、読み込みは 1 つだけ設定します。

//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 か所で処理するだけです。
//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 が失敗 (拒否) され、このインスタンスのコールバックが失敗 (拒否) された場合、then メソッドのコールバックは実行されなくなることを示しています。上記の使用例は、この問題を解決できます。

アプリケーション シナリオ 3: 複数のリクエスト結果が条件を満たしているかどうかを確認する

説明: WeChat アプレット プロジェクトで、フォームの入力コンテンツのセキュリティ検証を実行します。 , call クラウド機能によって記述されたメソッドです。フォームには検証が必要なフィールドが 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 を返します。どちらが先に完了したかに応じて、解決 (解決) または失敗 (拒否) のいずれかになります。 渡された反復が空の場合、返された Promise は永久に待機します。

反復に 1 つ以上の非 Promise 値および/または解決/拒否された 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: リクエスト タイムアウト プロンプト

説明:場合によっては、ニュースを読んでいる 1 秒後に、エレベーターに入った次の瞬間に、携帯電話のページに「ネットワークが良好ではありません」というメッセージが表示されることがあります。

//请求
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)//网络不佳
})

約束.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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。