promise.all如何运作?

时间:2015-07-08 17:10:04

标签: javascript promise es6-promise

我在承诺中开始挖掘'并发现了有趣的Promise.all。

在MDN中说明了

  

Promise.all(iterable)方法返回一个promise,它在iterable参数中的所有promise都已解析时解析。

这基本上意味着设置promises会在之后解析并且如果参数列表中的所有promise都已解决。我试图实现它。我做了简单的承诺ajax电话。

var get = function(url) {
    return new Promise(function(resolve,reject) {
        var xhtml=new XMLHttpRequest();

        xhtml.open("GET",url);
        xhtml.responseType = 'blob';
        xhtml.onload = function() {
            if(xhtml.status==200){
                resolve(xhtml.response);
            } else {
                reject(Error("Error"+statusText));
            }
        }
        xhtml.send();
    });

}

get("one.jpg").then(function(response){
    var blob = window.URL.createObjectURL(response);
    var img = document.createElement("img");

    console.log("Success"+response);

    img.src = blob;

    document.body.appendChild(img);
});

哪个工作正常。但在我尝试添加Promise.all之后,它抛出了一个错误。

Promise.all(get).then(function(response){alert("done")});

这就像我说的那样抛出一个错误“Promise.all的参数1无法转换为序列。” 所以我假设我没有得到promise.all的含义。 它是如何工作的?

4 个答案:

答案 0 :(得分:5)

Promise.all接受一个数组(或任何可迭代的)承诺,并在其中一个拒绝时满足或拒绝承诺。我认为如果我们实施它并理解我们为什么需要它,就会更容易理解。

一个常见的用例可能是等待窗口加载,服务器返回数据以运行一些代码:

// a function that returns a promise for when the document is ready.
function windowReady(){
    return new Promise(function(resolve){
         window.addEventListener('DOMContentLoaded', resolve);
    }); 
}

// function that returns a promise for some data
function getData(){
    return fetch("/").then(function(r){ return r.json() });
}

现在,我们希望他们两个同时执行 ,然后获得结果。这里有两个项目,但可能很容易就有5个要等待的东西,或者100个。所以我们使用Promise.all

Promise.all([windowReady(), getData()]).then(function(results){
     // results[1] is the data, it's all in an array.
});

让我们看看我们如何实现它:

function all(iterable){ // take an iterable 
  // `all` returns a promise.  
  return new Promise(function(resolve, reject){ 
    let counter = 0; // start with 0 things to wait for
    let results = [], i;
    for(let p of iterable){
        let current = i;
        counter++; // increase the counter 
        Promise.resolve(p).then(function(res){ // treat p as a promise, when it is ready: 
          results[i] = res; // keep the current result
          if(counter === 0) resolve(results) // we're done
        }, reject); // we reject on ANY error
       i++; // progress counter for results array
    }
  });
}

或者,甚至更多的ES6:

let all = iterable => new Promise((resolve, reject) => { 
  let arr = [...iterable], c = arr.length, results = [];
  arr.map(Promise.resolve, Promise).
      map((p, i) => p.then(v => { 
        r[i] = v;
        if(--c === 0) resolve(r);
      } , reject));
});

答案 1 :(得分:4)

您的get函数返回Promise。您只是传递对get函数的引用。您必须传递Promises

的数组
Promise.all([get("one.jpg")]).then(...);

答案 2 :(得分:2)

TLDR:

Promise.all是一种Javascript方法,它以可迭代(例如Array)的promise作为参数,并在可迭代参数中的 all 有promise时返回单个promise已解决(或当可迭代参数不包含诺言时)。它使用已解析值的数组进行解析,并使用第一个被拒绝的Promise的单个值来拒绝。

示例:

var promise1 = Promise.resolve(5);
var promise2 = Math.random() > 0.5? 1 : Promise.reject(1); // either resolves or rejects
var promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('foo'), 1000);
});

Promise.all([promise1, promise2, promise3]).then((val) => {
  console.log(val);
}).catch((val) => {
  console.log(val);
});

在上面的示例中,3个诺言作为数组传递到Promise.all函数中。承诺1和3始终会解决。承诺2基于随机Nr生成器解析或拒绝。然后,此Promise.all方法将基于随机Nr生成器返回已解决或被拒绝的Promise。

然后可以根据从then()返回的这个诺言调用catch()方法和Promise.all方法。 then()方法获取所有解析值的数组,在这种情况下为[5, 1, 'foo']catch()方法获取第一个被拒绝的Promise的值,在此示例中为1

何时使用:

当您要执行多个异步操作并且需要在异步操作后处理结果时,此方法非常有用。使用Promise.all时,可以同时处理所有promise,同时仍然可以对所有传入数据进行操作。

例如,当我们需要使用多个AJAX请求获取信息并将数据组合成有用的东西时。必须等待所有数据可用,否则我们将尝试合并不存在的数据,这会导致问题。

答案 3 :(得分:0)

Promise.all(iterables)函数返回一个Promise,这里我们提供多个Promises作为参数。 Promise.all(iterables)函数仅在所有promise(参数)都已解析后才返回promise。 当第一个诺言参数拒绝时,它就会拒绝。

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
// expected output: Array [3, 42, "foo"]
});

语法:

Promise.all(func1,func2 [,funcN])

参数:

更多信息,请访问-https://www.oodlestechnologies.com/blogs/An-Introduction-To-Promise.all-Function