如何在数组的 forEach 循环中使用 promise 来填充对象
How to use promise in forEach loop of array to populate an object
我是 运行 一个数组上的 forEach 循环并进行两次调用 return 承诺,我想填充一个对象说 this.options
,然后用它。现在,如果我使用以下代码示例并首先进入 then 函数,我 运行 就会陷入异步问题。
$.when.apply($, someArray.map(function(item) {
return $.ajax({...}).then(function(data){...});
})).then(function() {
// all ajax calls done now
});
这是下面的工作代码,但它只适用于数组中的第一个元素,因为我在响应的 .then
中调用了结果函数。我想先对数组的所有元素进行所有提取,然后调用生成的函数来做某事。
array.forEach(function(element) {
return developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
self.resultingFunction(self.files)
}).catch ((error) = > {
console.log('Error: ', error);
})
});
如何在 forEach 循环完成后填充 self.files
对象,然后使用 files 对象调用生成的函数?
Promise.all()
在这里会有帮助:
var promises = [];
array.forEach(function(element) {
promises.push(
developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
}).catch ((error) = > {
console.log('Error: ', error);
})
);
});
Promise.all(promises).then(() =>
self.resultingFunction(self.files)
);
这会启动对每个项目的 AJAX 调用,在调用完成后将每次调用的结果添加到 self.files
并在所有调用完成后调用 self.resultingFunction()
.
编辑: 根据 Yury Tarabanko 的建议进行了简化。
以上已接受的解决方案略有不同:
var promises = array.map(function(element) {
return developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
}).catch ((error) = > {
console.log('Error: ', error);
})
});
Promise.all(promises).then(() =>
self.resultingFunction(self.files)
);
我用了Array.map
而不是Array.forEach
,这意味着我不需要先创建一个空数组,我只是重新使用现有的数组。
您可以查看 以获得极好的提示。此处给出的解决方案使用 Array#reduce()
来避免在执行任何工作之前必须累积所有 Promise,而不是使用 Promise.all()
.
下面的代码是对sync使用Promise的简单理解
let numArr = [1,2,3,4,5];
let nums=[];
let promiseList = new Promise(function(resolve,reject){
setTimeout(()=>{
numArr.forEach((val)=>{
nums.push(val);
});
resolve(nums);
},5000)
})
Promise.all([promiseList]).then((arrList)=>{
arrList.forEach((array)=>{
console.log("Array return from promiseList object ",array);
})
});
以上示例将数组 nums 保存 5 秒。它会在发布后打印在控制台上。
你可以使用.map
作为一个循环来开始对每个数组元素的Promise请求和return这些Promises的新数组。
我也使用了解构,但不确定我们在这里需要它。
await Promise.all([...arr.map(i => "our promise func"())]);
我是 运行 一个数组上的 forEach 循环并进行两次调用 return 承诺,我想填充一个对象说 this.options
,然后用它。现在,如果我使用以下代码示例并首先进入 then 函数,我 运行 就会陷入异步问题。
$.when.apply($, someArray.map(function(item) {
return $.ajax({...}).then(function(data){...});
})).then(function() {
// all ajax calls done now
});
这是下面的工作代码,但它只适用于数组中的第一个元素,因为我在响应的 .then
中调用了结果函数。我想先对数组的所有元素进行所有提取,然后调用生成的函数来做某事。
array.forEach(function(element) {
return developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
self.resultingFunction(self.files)
}).catch ((error) = > {
console.log('Error: ', error);
})
});
如何在 forEach 循环完成后填充 self.files
对象,然后使用 files 对象调用生成的函数?
Promise.all()
在这里会有帮助:
var promises = [];
array.forEach(function(element) {
promises.push(
developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
}).catch ((error) = > {
console.log('Error: ', error);
})
);
});
Promise.all(promises).then(() =>
self.resultingFunction(self.files)
);
这会启动对每个项目的 AJAX 调用,在调用完成后将每次调用的结果添加到 self.files
并在所有调用完成后调用 self.resultingFunction()
.
编辑: 根据 Yury Tarabanko 的建议进行了简化。
以上已接受的解决方案略有不同:
var promises = array.map(function(element) {
return developer.getResources(element)
.then((data) = > {
name = data.items[0];
return developer.getResourceContent(element, file);
})
.then((response) = > {
fileContent = atob(response.content);
self.files.push({
fileName: fileName,
fileType: fileType,
content: fileContent
});
}).catch ((error) = > {
console.log('Error: ', error);
})
});
Promise.all(promises).then(() =>
self.resultingFunction(self.files)
);
我用了Array.map
而不是Array.forEach
,这意味着我不需要先创建一个空数组,我只是重新使用现有的数组。
您可以查看 Array#reduce()
来避免在执行任何工作之前必须累积所有 Promise,而不是使用 Promise.all()
.
下面的代码是对sync使用Promise的简单理解
let numArr = [1,2,3,4,5];
let nums=[];
let promiseList = new Promise(function(resolve,reject){
setTimeout(()=>{
numArr.forEach((val)=>{
nums.push(val);
});
resolve(nums);
},5000)
})
Promise.all([promiseList]).then((arrList)=>{
arrList.forEach((array)=>{
console.log("Array return from promiseList object ",array);
})
});
以上示例将数组 nums 保存 5 秒。它会在发布后打印在控制台上。
你可以使用.map
作为一个循环来开始对每个数组元素的Promise请求和return这些Promises的新数组。
我也使用了解构,但不确定我们在这里需要它。
await Promise.all([...arr.map(i => "our promise func"())]);