Promise.all的顺序执行
Sequential execution of Promise.all
你好,我需要一个接一个地执行承诺,我如何使用 promise.all 实现这一点,任何帮助都很棒。下面是我目前正在使用的代码示例,但它是并行执行的,因此搜索将无法正常工作
public testData: any = (req, res) => {
// This method is called first via API and then promise is triggerd
var body = req.body;
// set up data eg 2 is repeated twice so insert 2, 5 only once into DB
// Assuming we cant control the data and also maybe 3 maybe inside the DB
let arrayOfData = [1,2,3,2,4,5,5];
const promises = arrayOfData.map(this.searchAndInsert.bind(this));
Promise.all(promises)
.then((results) => {
// we only get here if ALL promises fulfill
console.log('Success', results);
res.status(200).json({ "status": 1, "message": "Success data" });
})
.catch((err) => {
// Will catch failure of first failed promise
console.log('Failed:', err);
res.status(200).json({ "status": 0, "message": "Failed data" });
});
}
public searchAndInsert: any = (data) => {
// There are database operations happening here like searching for other
// entries in the JSON and inserting to DB
console.log('Searching and updating', data);
return new Promise((resolve, reject) => {
// This is not an other function its just written her to make code readable
if(dataExistsInDB(data) == true){
resolve(data);
} else {
// This is not an other function its just written her to make code readable
insertIntoDB(data).then() => resolve(data);
}
});
}
我在 google 中查找并看到 reduce 会有所帮助我将不胜感激任何关于如何将其转换为 reduce 或您建议的任何方法的帮助(.map 中的并发不起作用)
不幸的是,Promises 不允许对其流程进行任何控制。这意味着 -> 一旦你创建了新的 Promise,它将按照他们喜欢的方式执行它的异步部分。
Promise.all
不会更改它,它的唯一目的是检查您放入其中的所有承诺,并在所有承诺完成(或其中之一失败)后解决。
为了能够创建和控制异步流程,最简单的方法是将 Promise 的创建包装到函数中并创建某种工厂方法。然后,无需预先创建所有承诺,您只需在需要时只创建一个承诺,等到它被解决,然后它继续以相同的行为。
async function doAllSequentually(fnPromiseArr) {
for (let i=0; i < fnPromiseArr.length; i++) {
const val = await fnPromiseArr[i]();
console.log(val);
}
}
function createFnPromise(val) {
return () => new Promise(resolve => resolve(val));
}
const arr = [];
for (let j=0; j < 10; j++) {
arr.push(createFnPromise(Math.random()));
}
doAllSequentually(arr).then(() => console.log('finished'));
PS: 不用async/await也可以使用标准的promise-chains,但是需要递归实现。
如果有人关心 ESLint 抱怨使用“for”和“循环中没有等待”,这里是上述答案的 typescript ESLint 友好版本:
async function runPromisesSequentially<T>(promises: Array<Promise<T>>):Promise<Array<T>> {
if (promises.length === 0) return [];
const [firstElement, ...rest] = promises;
return [await firstElement, ...(await runPromisesSequentially(rest))];
}
然后您可以将 Promise.all
替换为 runPromisesSequentially
。
你好,我需要一个接一个地执行承诺,我如何使用 promise.all 实现这一点,任何帮助都很棒。下面是我目前正在使用的代码示例,但它是并行执行的,因此搜索将无法正常工作
public testData: any = (req, res) => {
// This method is called first via API and then promise is triggerd
var body = req.body;
// set up data eg 2 is repeated twice so insert 2, 5 only once into DB
// Assuming we cant control the data and also maybe 3 maybe inside the DB
let arrayOfData = [1,2,3,2,4,5,5];
const promises = arrayOfData.map(this.searchAndInsert.bind(this));
Promise.all(promises)
.then((results) => {
// we only get here if ALL promises fulfill
console.log('Success', results);
res.status(200).json({ "status": 1, "message": "Success data" });
})
.catch((err) => {
// Will catch failure of first failed promise
console.log('Failed:', err);
res.status(200).json({ "status": 0, "message": "Failed data" });
});
}
public searchAndInsert: any = (data) => {
// There are database operations happening here like searching for other
// entries in the JSON and inserting to DB
console.log('Searching and updating', data);
return new Promise((resolve, reject) => {
// This is not an other function its just written her to make code readable
if(dataExistsInDB(data) == true){
resolve(data);
} else {
// This is not an other function its just written her to make code readable
insertIntoDB(data).then() => resolve(data);
}
});
}
我在 google 中查找并看到 reduce 会有所帮助我将不胜感激任何关于如何将其转换为 reduce 或您建议的任何方法的帮助(.map 中的并发不起作用)
不幸的是,Promises 不允许对其流程进行任何控制。这意味着 -> 一旦你创建了新的 Promise,它将按照他们喜欢的方式执行它的异步部分。
Promise.all
不会更改它,它的唯一目的是检查您放入其中的所有承诺,并在所有承诺完成(或其中之一失败)后解决。
为了能够创建和控制异步流程,最简单的方法是将 Promise 的创建包装到函数中并创建某种工厂方法。然后,无需预先创建所有承诺,您只需在需要时只创建一个承诺,等到它被解决,然后它继续以相同的行为。
async function doAllSequentually(fnPromiseArr) {
for (let i=0; i < fnPromiseArr.length; i++) {
const val = await fnPromiseArr[i]();
console.log(val);
}
}
function createFnPromise(val) {
return () => new Promise(resolve => resolve(val));
}
const arr = [];
for (let j=0; j < 10; j++) {
arr.push(createFnPromise(Math.random()));
}
doAllSequentually(arr).then(() => console.log('finished'));
PS: 不用async/await也可以使用标准的promise-chains,但是需要递归实现。
如果有人关心 ESLint 抱怨使用“for”和“循环中没有等待”,这里是上述答案的 typescript ESLint 友好版本:
async function runPromisesSequentially<T>(promises: Array<Promise<T>>):Promise<Array<T>> {
if (promises.length === 0) return [];
const [firstElement, ...rest] = promises;
return [await firstElement, ...(await runPromisesSequentially(rest))];
}
然后您可以将 Promise.all
替换为 runPromisesSequentially
。