我在承诺中开始挖掘'并发现了有趣的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的含义。 它是如何工作的?
答案 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