Home  >  Article  >  Web Front-end  >  ES6 new feature: Delayed object Promise built in JavaScript code details

ES6 new feature: Delayed object Promise built in JavaScript code details

黄舟
黄舟Original
2017-03-07 14:26:431425browse

Basic use of Promise:

Using Promise is to solve the problem of callback functions nested callback functions during JS asynchronous execution. More Concisely control the function execution process;

instantiate Promise through new. The constructor requires two parameters. The first parameter is the function resolve that will be executed after the function is successfully executed. The second function Reject the function that will be executed after the function execution fails:

new Promise(function(resolve , reject) {
});

Through Promise, we write the callback function in a linear manner instead of layer by layer. This function has four layers Callback;

fn("args", function(a) {
    fn1("foo", function(b) {
        fn2("bar", function(c) {
            fn3("baz", function(d) {
                alert("回调成功,获知的内容为:"+a+b+c+d)
            })
        })
    })
})

The above Demo only contains successful callbacks. If failed callbacks are also counted, it will be more troublesome;

If we use Promise, we can modify it to linear The code is more in line with reading habits, just write the logic under the then function;

new Promise(function(resolve , reject) {
    resolve(1);
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(2);
    });
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(3);
    });
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(4);
    });
}).then(function(val) {
    console.log(val);
});

This is an example of ajax asynchronously obtaining data, we used the callback function;

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<script>
    var callback = function(res) {
        console.log(res);
    };
    var ajax = function(url, callback) {
        var r = new XMLHttpRequest();
        r.open("GET", url, true);
        r.onreadystatechange = function () {
            if (r.readyState != 4 || r.status != 200) return;
            var data = JSON.parse(r.responseText);
            callback(data);
        };
        r.send();
    };
    //执行请求:
    ajax("http://www.filltext.com?rows=10&f={firstName}", callback);
    //再做别的事情;
</script>
</body>
</html>

Because ES6 has built-in Promise, we can rewrite the above callback into a promise method. First, the ajax function returns a Promise object;

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <script>
        var callback = function(res) {
            console.log(res);
        };
        var ajax = function(url) {
            return new Promise(function(resolve, reject) {
                var r = new XMLHttpRequest();
                r.open("GET", url, true);
                r.onreadystatechange = function () {
                    if (r.readyState != 4 || r.status != 200) return;
                    var data = JSON.parse(r.responseText);
                    resolve(data);
                };
                r.send();
            })
        };
        //执行请求:
        ajax("http://www.filltext.com?rows=10&f={firstName}").then(function(data) {
            callback(data);
        });
        //再做别的事情;
    </script>
</body>
</html>

Three states of Promise instances:

Each instantiated Promise has three states; pending (waiting) rejected (rejected) resolved (resolved). The default state is pending. If resolve() is executed, then the state of this promise will change For resolve, if reject() is executed, then the status of the promise will become rejected, and these statuses are irrevocable. Once changed, they will not change again;

then method:

promise has a then method. The then method receives two parameters. The first is the success callback of the function, and the second is the failure callback of the function:

var promise = new Promise(function(resolve , reject) {
    resolve(); //执行成功回调;
});
console.log(0);
promise.then(function(val) {
    console.log(1); 
}, function() {
    console.log("失败");
});
console.log("2");
var promise = new Promise(function(resolve , reject) {
    reject();
});
console.log(0);
promise.then(function(val) {
    console.log(1);
}, function() {
    console.log("失败");
});
console.log("2");

The then method returns a different value each time. Promise instance, the first parameter of then is the success callback. The parameters of this success callback are: The parameters of the resolve method executed by the previous Promise instance;

Generally speaking, the then method will return the current promise , if a new Promise instance is returned in the then method, then then will return the new Promise instance. Using this feature, you can implement multi-layer callbacks;

new Promise(function(resolve , reject) {
    resolve(1);
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(2);
    });
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(3);
    });
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve , reject) {
        resolve(4);
    });
}).then(function(val) {
    console.log(val);
});

Regardless of whether the code is asynchronous or synchronous, you can use the then method of Promise. The synchronous code is written directly in the first parameter of the then method, and the required parameters are passed to the next then method through resolve.

If it is asynchronous code, just return a Promise instance directly:

new Promise(function(resolve , reject) {
    resolve(1);
}).then(function(val) {
    console.log(val);
    return 2;
}).then(function(val) {
    console.log(val);
    return 3;
}).then(function(val) {
    console.log(val);
    return new Promise(function(resolve,reject) {
        //异步操作些这里
        resolve(4);
    });
}).then(function(val) {
    console.log(val);
    return 5;
}).then(function(val) {
    console.log(val);
});

catch method:

The catch method is the same as the failure callback. If the previous asynchronous function throws When an error occurs, the error will be caught, and the catch method or failure callback will be executed;

var promise = new Promise(function(resolve , reject) {
    resolve(); //执行成功回调;
});
console.log(0);
promise.then(function(val) {
    console.log("成功");
    throw new Error("heheda");
}).catch(function(e) {
    console.log(e);
}).then(function() {
    console.log("继续执行");
});

The error in the Promise will be passed layer by layer. If the error is not caught, it will be passed to the next one. promise object, until it is captured, and then continue to execute:

new Promise(function(resolve , reject) {
    resolve(1);
}).then(function(val) {
        console.log(val);
        return new Promise(function(resolve , reject) {
            throw new Error("err");
        });
    }).then(function(val) {
        console.log(val);
        return new Promise(function(resolve , reject) {
            resolve(3);
        });
    }).then(function(val) {
        console.log(val);
        return new Promise(function(resolve , reject) {
            resolve(4);
        });
    }).then(function(val) {
        console.log(val);
    }).catch(function(err) {
        console.log(err);
    }).then(function() {
        console.log("继续执行")
    })

Four methods of constructor Promise:

Constructor Promise has four methods, Promise .all, Promise.race, Promise.reject, Promise.resolve:

Promise.all(iterable)
Returns a promise object when all promises in the iterable parameters are resolved After it is resolved, the promise will also be resolved

Please note that the all method is a method of the Promise function, not an instance method. The parameter is an array, and the array is full of Promise Example :

var p0 = new Promise(function(resolve) {
    setTimeout(function() {
        resolve(0)
    },1000);
})
var p1 = new Promise(function(resolve) {
    setTimeout(function() {
        resolve(1)
    },2000);
})
var p2 = new Promise(function(resolve) {
    setTimeout(function() {
        resolve(2)
    },3000);
})
Promise.all([p0,p1,p2]).then(function(arr) {
    console.log(arr)
})

Promise.race(iterable)

When any child promise in the iterable parameter succeeds or fails, the parent promise will immediately Call the corresponding handle bound by the parent promise with the success return value or failure details of the child promise as a parameter, and return the promise object.

Promise.reject(reason)

Call the rejected handle of Promise and return this Promise object.

Promise.resolve(value)

Resolve a Promise object with the success value value. If the value is thenable (that is, with a then method), the returned Promise object will "follow" the value and adopt the final state of the value; otherwise, the return value will use this value to satisfy (fullfil) the returned Promise object.

Official example:

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<p id="log"></p>
<script>
    &#39;use strict&#39;;
    var promiseCount = 0;
    function testPromise() {
        var thisPromiseCount = ++promiseCount;

        var log = document.getElementById(&#39;log&#39;);
        log.insertAdjacentHTML(&#39;beforeend&#39;, thisPromiseCount + &#39;) 开始(同步代码开始)<br/>&#39;);

        // 我们创建一个新的promise: 然后用&#39;result&#39;字符串解决这个promise (3秒后)
        var p1 = new Promise(function (resolve, reject) {
            // 解决函数带着解决(resolve)或拒绝(reject)promise的能力被执行
            log.insertAdjacentHTML(&#39;beforeend&#39;, thisPromiseCount + &#39;) Promise开始(异步代码开始)<br/>&#39;);

            // 这只是个创建异步解决的示例
            window.setTimeout(function () {
                // 我们满足(fullfil)了这个promise!
                resolve(thisPromiseCount)
            }, Math.random() * 2000 + 1000);
        });

        // 定义当promise被满足时应做什么
        p1.then(function (val) {
            // 输出一段信息和一个值
            log.insertAdjacentHTML(&#39;beforeend&#39;, val + &#39;) Promise被满足了(异步代码结束)<br/>&#39;);
        });

        log.insertAdjacentHTML(&#39;beforeend&#39;, thisPromiseCount + &#39;) 建立了Promise(同步代码结束)<br/><br/>&#39;);
    }
    testPromise();
</script>
</body>
</html>

Now that we have Promise, we can encapsulate the XMLHttpRequest into a GET method for easy use:

function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    var req = new XMLHttpRequest();
    req.open(&#39;GET&#39;, url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.response);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}

Then use:

get(&#39;story.json&#39;).then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.error("Failed!", error);
});

The address of the fake data can be set by yourself, and it can be requested through the console. Pay attention to cross-domain issues;

The case of encapsulating XMLHttpRequest into Promise to load images asynchronously: http: //www.php.cn/

Others:

The above are just some basic knowledge of Promise, and there are some other knowledge points, because the ability is limited I won’t introduce them one by one (different parameters of Promise.resolve, use with Generator, additional methods of Promise, etc.);

Draw the running process of Promise, and you will have a better understanding of Promise. , Promise is still quite confusing

Browser support:

Chrome 32, Opera 1, Firefox 29, Safari 8, Microsoft Edge, these browsers are all supported by default;

The above are the new features of ES6: built-in JavaScript Delay object Promise code is introduced in detail. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn