When to use promise.all()?

前端 未结 8 823
孤街浪徒
孤街浪徒 2020-12-02 17:27

This is more of a conceptual question. I understand the Promise design pattern, but couldn\'t find a reliable source to answer my question about promise.all():<

相关标签:
8条回答
  • 2020-12-02 17:56

    If you are interested only Promise.all then read below Promise.all

    Promise (usually they are called "Promise") - provide a convenient way to organize asynchronous code.

    Promise - is a special object that contains your state. Initially, pending ( «waiting"), and then - one of: fulfilled ( «was successful") or rejected ( «done with error").

    On the promise to hang callbacks can be of two types:

    • unFulfilled - triggered when the promise in a state of "completed successfully."
    • Rejected - triggered when the promise in the "made in error."

    The syntax for creating the Promise:

    var promise = new Promise(function(resolve, reject) {
      // This function will be called automatically
    
      // It is possible to make any asynchronous operations,
      // And when they will end - you need to call one of:
      // resolve(result) on success
      // reject(error) on error
    })
    

    Universal method for hanging handlers:

    promise.then(onFulfilled, onRejected)
    
    • onFulfilled - a function that will be called with the result with resolve.

    • onRejected - a function that will be called when an error reject.

    With its help you can assign both the handler once, and only one:

    // onFulfilled It works on success
    promise.then(onFulfilled)
    // onRejected It works on error
    promise.then(null, onRejected)
    

    Synchronous throw - the same that reject

    'use strict';
    
    let p = new Promise((resolve, reject) => {
      // то же что reject(new Error("o_O"))
      throw new Error("o_O");
    });
    
    p.catch(alert); // Error: o_O
    

    Promisification Promisification - When taking asynchronous functionality and make it a wrapper for returning PROMIS.

    After Promisification functional use often becomes much more convenient.

    As an example, make a wrapper for using XMLHttpRequest requests

    httpGet function (url) will return PROMIS, which upon successful data loading with the url will go into fulfilled with these data, and in case of error - in rejected with an error information:

    function httpGet(url) {
    
        return new Promise(function(resolve, reject) {
    
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
    
            xhr.onload = function() {
                if (this.status == 200) {
                    resolve(this.response);
                } else {
                    var error = new Error(this.statusText);
                    error.code = this.status;
                    reject(error);
                }
            };
    
            xhr.onerror = function() {
                reject(new Error("Network Error"));
            };
    
            xhr.send();
        });
    
    }
    

    As you can see, inside the function XMLHttpRequest object is created and sent as usual, when onload / onerror are called, respectively, resolve (at the status 200) or reject.

    Using:

    httpGet("/article/promise/user.json")
        .then(
            response => alert(`Fulfilled: ${response}`),
            error => alert(`Rejected: ${error}`)
        );
    

    Parallel execution

    What if we want to implement multiple asynchronous processes simultaneously and to process their results?

    The Promise class has the following static methods.

    Promise.all(iterable)

    Call Promise.all (iterable) receives an array (or other iterable object) and returns PROMIS PROMIS, which waits until all transferred PROMIS completed, and changes to the state "done" with an array of results.

    For example:

    Promise.all([
        httpGet('/article/promise/user.json'),
        httpGet('/article/promise/guest.json')
    ]).then(results => {
        alert(results);
    });
    

    Let's say we have an array of URL.

    let urls = [
      '/article/promise/user.json',
      '/article/promise/guest.json'
    ];
    

    To download them in parallel, you need to:

    1. Create for each URL corresponding to PROMIS.
    2. Wrap an array of PROMIS in Promise.all.

    We obtain this:

    'use strict';

    let urls = [
      '/article/promise/user.json',
      '/article/promise/guest.json'
    ];
    
    Promise.all( urls.map(httpGet) )
      .then(results => {
        alert(results);
    });
    

    Note that if any of Promise ended with an error, the result will

    Promise.all this error.

    At the same time the rest of PROMIS ignored.

    For example:

    Promise.all([
        httpGet('/article/promise/user.json'),
        httpGet('/article/promise/guest.json'),
        httpGet('/article/promise/no-such-page.json') // (нет такой страницы)
    ]).then(
        result => alert("не сработает"),
        error => alert("Ошибка: " + error.message) // Ошибка: Not Found
    )
    

    In total:

    • Promise - is a special object that stores its state, the current result (if any), and callbacks.
    • When you create a new Promise ((resolve, reject) => ...) function argument starts automatically, which should call resolve (result) on success, and reject (error) - error.
    • Argument resolve / reject (only the first, and the rest are ignored) is passed to handlers on this Promise.
    • Handlers are appointed by calling .then / catch.
    • To transfer the results from one processor to another using Channing.

    https://www.promisejs.org/patterns/

    0 讨论(0)
  • 2020-12-02 18:02

    Promise.all passes an array of values from all the promises in the iterable object that it was passed.

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

    var isCallFailed = false;
    function myEndpoint1() {
      return isCallFailed ? Promise.reject("Bohoo!") :Promise.resolve({"a":"a"});
    }
    function myEndpoint2() {
      return Promise.resolve({"b":"b"});
    }
    
    Promise.all([myEndpoint1(), myEndpoint2()])
    .then(values => {
      var data1 = values[0];
      var data2 = values[1];
      alert("SUCCESS... data1: " + JSON.stringify(data1) + "; data2: " +  JSON.stringify(data2));
    })
    .catch(error => {
      alert("ERROR... " + error);
    });
    

    you can try another case by making isCallFailed = true.

    0 讨论(0)
提交回复
热议问题