非同期プログラミング-Promise


記事の目次
  • Promiseの基本的な使い方
  • Promiseアプリケーション:ajax
  • Promiseチェーン呼び出し
  • Promise異常処理
  • の2つの方法
  • 方式の違い
  • グローバル捕獲異常イベント
  • Promise静的方法
  • Promise.resove()
  • Promise.reject()
  • Promise並列実行
  • Promise.all([])
  • Promise.race([])
  • Promise実行タイミング
  • Promiseの基本的な使い方
  • Promiseはあることを承諾することに相当します.もし成功したら、レレスの方法を調べます.失敗したら、リジェクトの方法を返します.
  • の方法は実行時にキューに入れて
  • を実行する.
    console.log(`------------------------------
    ----Promise
    ------------------------------`
    ) // “ ” const promise = new Promise((resolve, reject) => { //resolve reject // // resolve(100) // reject(new Error("this is reject!")) }) // Promise promise.then((value) => { // console.log("resolved", value) }, (error) => { // console.log("rejected", error) }) //Promise , Promise.then , 。 // then(resolve,reject) resolve reject , console.log("end of the part") /** (resolve): end of the part resolved 100 */ /** (reject): end of the part rejected Error: this is reject! at 01.promise.js:14 at new Promise () at Object. (01.promise.js:8) at __webpack_require__ (bootstrap:19) at Object. (bootstrap:83) at __webpack_require__ (bootstrap:19) at bootstrap:83 at bootstrap:83 */
    Promise応用:ajax
    console.log(`------------------------------
    ----Promise ajax
    ------------------------------`
    ) const ajax = function (url) { return new Promise(function (resolve, reject) { let xhr = new XMLHttpRequest() xhr.open("GET", url) xhr.responseType = "json" xhr.onload = function () { if (this.status === 200) { resolve(200) } else { reject(this.statusText) } } xhr.send() }) } ajax("/api/users.jsona").then((value) => { console.log(value) //200 }, (err) => { console.log(err) //Not Found })
    Promiseチェーン呼び出し
  • Promise.then(…)は、新たなPromiseオブジェクト
  • を返します.
  • 各then()方法は、実際には、前のthen()方法のために戻ったPromiseオブジェクトに、状態が明確になった後のコールバックを追加する.
  • の前のthen()の方法におけるコールバック関数の戻り値は、後のthen()の方法によるコールバックパラメータ
  • となる.
  • コールバック中にPromiseが戻ってきたら、その後のthen()メソッドのコールバックはその終了を待つことができます.
    console.log(`------------------------------
    ----Promise
    ------------------------------`
    ) const ajax = function (url) { return new Promise(function (resolve, reject) { let xhr = new XMLHttpRequest() xhr.open("GET", url) xhr.responseType = "json" xhr.onload = function () { if (this.status === 200) { resolve(200) } else { reject(this.statusText) } } xhr.send() }) } let promise = ajax("/api/users.json") /** then() Promise */ let promise2 = promise.then(function (value) { console.log(1111) }) console.log(promise2) // Promise {} /** Promise */ console.log(promise == promise2) //false /** then() then() Promise */ let promise3 = promise2.then(function (value) { console.log(2222) }).then(function (value) { console.log(5555) }).then(function (value) { console.log(4444) }) /** 1111 2222 5555 4444 */ /** then() , then() */ promise3.then(function (value) { console.log("first:", value) return "params test" }).then(function (value) { console.log("second:", value) }) /** first:undefined seconde:params test */
    Promise異常処理
    二つの方法
  • オンリーチューニング関数を使用して
  • を捕捉する.
  • catch()方法を用いて
  • を捕捉する.
  • catch()方法はthen()方法の別名で、catch(function)==then(undefined,function){…)
  • catch()は、現在のPromiseオブジェクト
  • を返します.
    /**      :  then()    onReject      
     *           promise       
     */
    ajax("/api/users.json").then(function (value) {
         
        console.log(value)
        noFunction()
    }, function (err) {
         
        console.log(err)
    })
    /**  
        Uncaught (in promise) ReferenceError: noFunction is not defined
    at VERSION (index.js:154)
     */
    
    
    /**      : then()       catch()  
     *       Promise       
     * catch()   then()     ,catch(function(err){...}) === then(undefined,function(err){...})
     */
    ajax("/api/users.json").then(function (value) {
         
        console.log(value)
        noFunction()
    }).catch(function (err) {
         
        console.log(err)
    })
    /**  
        ReferenceError: noFunction is not defined
    at index.js:166
     */
    
    二つの方式の違い
  • オンリーチューニング関数を使って捕獲された異常は、前に戻ったプロミスオブジェクトに発生した異常
  • である.
  • で、catchを使って捕獲された異常は、現在戻ってきたPromiseオブジェクトに発生する異常
  • である.
    //  1:
    ajax("/api/users.json").then(function (value) {
         
        console.log(value)
        return ajax("/error-url") //   
    }, function (err) {
         
        console.log(err) //    
    })
    
    //  2::
    ajax("/api/users.json").then(function (value) {
         
        console.log(value)
        return ajax("/error-url") //   
    }).catch(function (err) {
         
        console.log(err) //Error: Not Found at XMLHttpRequest.xhr.onload (index.js:147)
    })
    
    グローバルキャプチャ異常イベント
  • unhandledrejectionイベント
  • /**  window  */
    
    window.addEventListener('unhandledrejection', event => {
         
        const {
          reason, promise } = event
        // reason :Promise    ,         
        //promise :     Promise  
        event.preventDefault()
    }, false)
    
    /**  node  */
    process.on('unhandledRejection', (reason, promise) => {
         
        console.log(reason, promise)
    })
    
    Promise静的方法
    Promise.resove()
  • 快速に成功したPromiseオブジェクトを作成します.
  • は、一つの値をPromiseオブジェクトに素早く変換します.は、成功した値を返します.また、then()の方法で入手したvalueは、この値です.
  • 入力された値が他のPromiseオブジェクトであれば、Promise.resove()後の値は元のPromiseオブジェクト
  • である.
  • によってもたらされるのがthen方法を有するものであり、onFulfilledおよびonRejecedパラメータを受け取ることができるオブジェクトであれば、同じくPromiseオブジェクト
  • に変換することができる.
    let promise1 = Promise.resolve("my value")
    promise1.then(function (val) {
         
        console.log(val) // my value
    })
    let promise2 = Promise.resolve(promise1)
    console.log(promise1 === promise2) //true
    Promise.resolve({
         
        then: function (onFulfilled, onRejected) {
         
            onFulfilled("then object to promise object")
        }
    })
        .then(function (value) {
         
            console.log(value) //then object to promise object
        })
    
    Promise.reject()
  • 失敗したPromiseオブジェクトを素早く作成する
  • Promise.reject(new Error("my error in reject static function"))
        .catch(function (err) {
         
            console.log(err) //Error: my error in reject static function
        })
    
    Promise並行実行
  • により複数の独立インターフェースが実行される場合、並列に
  • を実行することができる.
    Promise.all([])
  • Promiseオブジェクト配列を受け入れる
  • すべてのPromise要求が完了し、成功したら、集団で一つの配列に戻ります.配列には各Promiseの結果が含まれています.
  • Promise要求が失敗したら、全部失敗します.
    [
        {
         
            "name": "asd",
            "age": 32
        },
        {
         
            "name": "bbb",
            "age": 12
        }
    ]
    
    (users.json)
    [
        {
         
            "className": "A1 ",
            "level": "   "
        },
        {
         
            "className": "A5 ",
            "level": "   "
        }
    ]
    
    (classes.json)
    const ajax = function (url) {
         
        return new Promise(function (resolve, reject) {
         
            let xhr = new XMLHttpRequest()
            xhr.open("GET", url)
            xhr.responseType = "json"
            xhr.onload = function () {
         
                if (this.status === 200) {
         
                    resolve(this.response)
                } else {
         
                    reject(this.statusText)
                }
            }
            xhr.send()
        })
        }
    
    //    ,      
    //   Promise    
    let promiseAll = Promise.all([
        ajax("/api/users.json"),
        ajax("/api/classes.json")
    ])
    //    Promise    
    promiseAll.then(function (values) {
         
        console.log(values) // [Array(2), Array(2)]
    })
    //     ,     
    let promiseAllFail = Promise.all([
        ajax("/api/users.json"),
        ajax("/api/none-file.json") //   
    ])
    promiseAllFail.then(function (values) {
         
        console.log(values)
    }).catch(function (err) {
         
        console.log(err) //Not Found
    })
    
  • は、要求されたリンクアドレス(js)
  • を一つのjsonファイルに集中的に管理することができる.
    {
         
        "users": "/api/users.json",
        "classes": "/api/classes.json"
    }
    
    (urls.json)
    ajax("/api/urls.json")
        .then(res => {
         
            const urls = Object.values(res)
            const promiseArray = urls.map(url => ajax(url))
            return Promise.all(promiseArray)
        })
        .then(res => {
         
            console.log(res) //[Array(2), Array(2)]
        })
    
    Promise.race([])
  • はPromiseの配列
  • に伝えられました.
  • は、最初にPromise
  • を完了するために戻ってきます.
    const ajax = function (url) {
         
        return new Promise(function (resolve, reject) {
         
            let xhr = new XMLHttpRequest()
            xhr.open("GET", url)
            xhr.responseType = "json"
            xhr.onload = function () {
         
                if (this.status === 200) {
         
                    resolve(this.response)
                } else {
         
                    reject(this.statusText)
                }
            }
            xhr.send()
        })
    }
        
    const normal = ajax("/api/users.json")
    const timeout = new Promise((resolve, reject) => {
         
        setTimeout(() => {
         
            reject("it is timeout!")
        }, 500)
    })
    Promise.race([
        normal,
        timeout
    ])
        .then(res => {
         
            console.log(res)
        })
        .catch(err => {
         
            console.log(err) //  3G    :it is timeout!
        })
    
    Promise実行タイミング
  • マイクロタスク:本ラウンド実行タスク末尾実行
  • マクロタスク:新しいタスク
  • 現在の非同期コールのほとんどは、マクロタスク
  • に属しています.
  • Promise、MuttionObserver、process.nextTickは、マイクロタスク
  • に属します.
    console.log("programming start")
    setTimeout(() => {
          //setTimeout      ,             
        console.log("setTimeout")
        new Promise((resolve, reject) => {
         
            console.log("inner promise 1")
            resolve("ok")
        })
            .then(res => {
         
                console.log("inner promise 2")
            })
    }, 0)
    new Promise((resolve, reject) => {
         //Promise    ,          
        console.log("promise 1")
        resolve("ok")
    })
        .then(res => {
         
            console.log("promise 2")
        })
        .then(res => {
         
            console.log("promise 3")
        })
    console.log("programming end")
    
    
    /**  
        programming start
        promise 1
        programming end
        promise 2
        promise 3
        setTimeout
        inner promise 1
        inner promise 2
     */