promise,generaotr,asyncの応用

2783 ワード

jquery時代には,a,b,cのリクエストがいくつかあり,各リクエストが前のリクエストから返されたデータを使用する必要がある場合,このようなコードを書く.
$.ajax({url:a, data:null, success: (adata) => {
    $.ajax({url:b, data: adata, success: (bdata) => {
        $.ajax({url:c, data:bdata, success: (cdata) => {
            console.log(cdata)
        }})
    }})
}})

多層のコールバックに陥り、美しくもないことがわかります.この時、非同期問題を解決する方法がいくつか生まれた.
Promise
Promise自体は1つのコンストラクション関数で、中のパラメータは1つの関数で、new Promise( (resolve, reject) => {} )で、関数に2つのパラメータがあることがわかります.Promiseは全部で3つの状態があり、pending(進行中)、fulfilled(成功)、rejected(失敗)です.状態の変化はpromiseのthenメソッドに入って次の操作を行います.多層コールバックの場合、このように書くことができます
const log = console.log.bind(console);
new Promise((resolve, reject) => {

    axios({
        method: "post",
        url: "http://api.nohttp.net/upload",
        data: JSON.stringify({ age: 11 }),
        headers: { 'Content-Type': 'application/json', }
    }).then((res) => resolve(res.data))//  resolve      , 
          then      。

}).then((adata) => new Promise((resolve, reject) => {

    axios({
        method: "post",
        url: "http://api.nohttp.net/upload",
        data: JSON.stringify(adata),
        headers: { 'Content-Type': 'application/json', }
    }).then((res) => resolve(res.data))

})).then((res) => log(res)).catch((err) => log(err))

catchはエラーをキャプチャしたときに実行されます.彼に実行させたらPromiseで実行されます.reject(err)、resolveと同じように、catchメソッドはrejectから渡されたパラメータを受信します.
2つのリクエストa,b,bがある場合はaが返すデータは必要ありませんが、a,bの両方のリクエストが戻ってから何らかの操作をしたい場合はPromise.all()
let a = new Promise(...);
let b = new Promise(...);
Promise.all( [a, b] ,(data) => {
     console.log(data)//data      Promise     ,        
})

Generator
const log = console.log.bind(console);
    let request = (param) => new Promise((resolve, reject) => {
        axios({
            method: "post",
            url: "http://api.nohttp.net/upload",
            data: JSON.stringify(param),
            headers: { 'Content-Type': 'application/json', }
        }).then((res) => {
            resolve(res.data)
        })
    });


    function* foo() {
        const data = yield request({ age: 11 });
        const finallyData = yield request({ ...data })
        log(finallyData)
        return
    }

    function run(gen) {
        var g = gen();

        function go(data) {

            var result = g.next(data);
            if (result && result.done) return;
            result.value.then(function (data) {
                go(data);
            });
        }

        go();
    }

    run(foo);