做多个 .fetch() 承诺
Do multiple .fetch() promises
我想获取多张图像并将它们转换为 blob。我是promises的新手,我试过了,但是我无法通过。
在下面,一个.fetch()
承诺
fetch('http://cors.io/?u=http://alistapart.com/d/_made/d/ALA350_appcache_300_960_472_81.jpg')
.then(function(response) {
return response.blob();
})
.then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
document.getElementById('myImage').src = objectURL;
});
现在有多个 .fetch()
承诺(不起作用)
var promises = [];
for (var i = values.length - 1; i >= 0; i--) {
promises.push(fetch(values[i]));
}
Promise
.all(promises)
.then(function(response) {
for (var i = response.length - 1; i >= 0; i--) {
return response[i].blob();
}
})
.then(function(blob) {
console.log(blob.length); //undefined !!!
for (var i = blob.length - 1; i >= 0; i--) {
console.log(blob[i]);
lcl_images[i].value = URL.createObjectURL(blob[i]);
document.getElementById(lcl_images[i].id).src = objectURL;
}
})
.catch(function(error) {
console.log(error);
});
您是在第一个响应后从 then 处理程序 returning,而您需要做的是 return blob 列表:
Promise
.all(promises)
.then(function(response) {
// CHANGED HERE
var blobPromises = [];
for (var i = response.length - 1; i >= 0; i--) {
blobPromises.push(response[i].blob());
}
return Promise.all(blobPromises);
})
.then(function(blob) {
console.log(blob.length);
for (var i = blob.length - 1; i >= 0; i--) {
lcl_images[i].value = URL.createObjectURL(blob[i]);
document.getElementById(lcl_images[i].id).src = objectURL;
}
})
.catch(function(error) {
console.log(error);
});
一般规则是,承诺链成功路径中完全同步的中间步骤可以与下一步合并,从而允许从链中省略一个 then()
。
该声明实际上有一个附带条件,涉及中间捕获,但足以满足此答案。
因此,如果 .blob()
方法是真正同步的(它 return 是一个值),则只需要一个 .then()
,而不是两个。
这里有两种方法,都利用了 Array.prototype.map(),并且都应该有效(尽管它们在错误情况下会有所不同):
1.简单 .map()
详细 Promise.all()
var promises = values.reverse().map(fetch); // you may need .reverse(), maybe not. I'm not 100% sure.
return Promise.all(promises).then(function(responses) {
responses.forEach(function(r, i) {
var imageObj = lcl_images[i],
element = document.getElementById(imageObj.id);
imageObj.value = URL.createObjectURL(r.blob());
if(element) { //safety
element.src = imageObj.value;
}
});
return responses; // here, return whatever you want to be made available to the caller.
}).catch(function(error) {
console.log(error);
});
如果你愿意,你可以写:
return Promise.all(values.reverse().map(fetch)).then(function(responses) {
// ...
});
2。 .map()
中的详细信息遵循简单的 Promise.all()
var promises = values.reverse().map(function(val, i) {
return fetch(val).then(function(result) {
var imageObj = lcl_images[i],
element = document.getElementById(imageObj.id);
imageObj.value = URL.createObjectURL(result.blob());
if(element) { //safety
element.src = imageObj.value;
}
return result; // here, return whatever you want to be made available to the caller.
});
});
return Promise.all(promises).catch(function(error) { // return a promise to the caller
console.log(error);
});
备注:
如果任何一个 fetch()
失败,- (1) 将完全失败。
- (2) 将为所有 成功的 提取执行所有
imageObj.value ...
和 element.src = ...
内容,即使一个或多个 fetch()...
失败。任何一次失败都会导致 Promise.all(promises)
到 return 被拒绝的承诺。
- (1) 或 (2) 可能更合适,具体取决于您的需要。
- 还有其他错误处理的可能性。
- 如果两种方法都不起作用,那么最合理的解释是
.blob()
方法 return 是一个承诺,而不是一个值。
我想获取多张图像并将它们转换为 blob。我是promises的新手,我试过了,但是我无法通过。
在下面,一个.fetch()
承诺
fetch('http://cors.io/?u=http://alistapart.com/d/_made/d/ALA350_appcache_300_960_472_81.jpg')
.then(function(response) {
return response.blob();
})
.then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
document.getElementById('myImage').src = objectURL;
});
现在有多个 .fetch()
承诺(不起作用)
var promises = [];
for (var i = values.length - 1; i >= 0; i--) {
promises.push(fetch(values[i]));
}
Promise
.all(promises)
.then(function(response) {
for (var i = response.length - 1; i >= 0; i--) {
return response[i].blob();
}
})
.then(function(blob) {
console.log(blob.length); //undefined !!!
for (var i = blob.length - 1; i >= 0; i--) {
console.log(blob[i]);
lcl_images[i].value = URL.createObjectURL(blob[i]);
document.getElementById(lcl_images[i].id).src = objectURL;
}
})
.catch(function(error) {
console.log(error);
});
您是在第一个响应后从 then 处理程序 returning,而您需要做的是 return blob 列表:
Promise
.all(promises)
.then(function(response) {
// CHANGED HERE
var blobPromises = [];
for (var i = response.length - 1; i >= 0; i--) {
blobPromises.push(response[i].blob());
}
return Promise.all(blobPromises);
})
.then(function(blob) {
console.log(blob.length);
for (var i = blob.length - 1; i >= 0; i--) {
lcl_images[i].value = URL.createObjectURL(blob[i]);
document.getElementById(lcl_images[i].id).src = objectURL;
}
})
.catch(function(error) {
console.log(error);
});
一般规则是,承诺链成功路径中完全同步的中间步骤可以与下一步合并,从而允许从链中省略一个 then()
。
该声明实际上有一个附带条件,涉及中间捕获,但足以满足此答案。
因此,如果 .blob()
方法是真正同步的(它 return 是一个值),则只需要一个 .then()
,而不是两个。
这里有两种方法,都利用了 Array.prototype.map(),并且都应该有效(尽管它们在错误情况下会有所不同):
1.简单 .map()
详细 Promise.all()
var promises = values.reverse().map(fetch); // you may need .reverse(), maybe not. I'm not 100% sure.
return Promise.all(promises).then(function(responses) {
responses.forEach(function(r, i) {
var imageObj = lcl_images[i],
element = document.getElementById(imageObj.id);
imageObj.value = URL.createObjectURL(r.blob());
if(element) { //safety
element.src = imageObj.value;
}
});
return responses; // here, return whatever you want to be made available to the caller.
}).catch(function(error) {
console.log(error);
});
如果你愿意,你可以写:
return Promise.all(values.reverse().map(fetch)).then(function(responses) {
// ...
});
2。 .map()
中的详细信息遵循简单的 Promise.all()
var promises = values.reverse().map(function(val, i) {
return fetch(val).then(function(result) {
var imageObj = lcl_images[i],
element = document.getElementById(imageObj.id);
imageObj.value = URL.createObjectURL(result.blob());
if(element) { //safety
element.src = imageObj.value;
}
return result; // here, return whatever you want to be made available to the caller.
});
});
return Promise.all(promises).catch(function(error) { // return a promise to the caller
console.log(error);
});
备注:
-
如果任何一个
- (1) 将完全失败。
- (2) 将为所有 成功的 提取执行所有
imageObj.value ...
和element.src = ...
内容,即使一个或多个fetch()...
失败。任何一次失败都会导致Promise.all(promises)
到 return 被拒绝的承诺。 - (1) 或 (2) 可能更合适,具体取决于您的需要。
- 还有其他错误处理的可能性。
- 如果两种方法都不起作用,那么最合理的解释是
.blob()
方法 return 是一个承诺,而不是一个值。
fetch()
失败,