11

我开始挖掘 Promise 并发现了有趣的 Promise.all。

在 MDN 中指出

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

这基本上意味着 set Promise 在参数列表中的所有 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

4 回答 4

8

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

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

// 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 = 0;
    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));
});
于 2015-07-08T17:26:59.280 回答
4

您的get函数返回一个Promise. 您只是传递对get函数的引用。你必须传递一个数组Promises

Promise.all([get("one.jpg")]).then(...);
于 2015-07-08T17:13:03.967 回答
2

TLDR:

Promise.all是一种 Javascript 方法,它接受一个可迭代的(例如)承诺作为参数,并在可迭代参数中的所有承诺都已解决(或当可迭代参数不包含任何承诺时)Array返回单个承诺。它使用已解析值的数组进行解析,并使用第一个被拒绝的 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 个 PromisesPromise.all作为数组传递给函数。承诺 1 和 3 总是解决。Promise 2 根据随机 Nr 生成器解决或拒绝。然后,此 Promise.all 方法根据随机 Nr 生成器返回已解决或拒绝的 Promise。

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

何时使用:

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

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

于 2018-08-14T08:29:16.333 回答
0

Promise.all(iterables) 函数返回一个 Promise。这里我们提供多个 Promise 作为参数。Promise.all(iterables) 函数仅在所有承诺(参数)都已解决时才返回承诺。当第一个 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

免责声明:我为 oodles 技术工作

于 2019-01-30T17:53:48.467 回答