最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to guarantee sequential order with angular http rest api in for loop? - Stack Overflow

programmeradmin8浏览0评论

I'm trying to create a form that allows you to create multiple resources in sequential order.

Example below

Floor 1
Floor 2
Floor 3
...
Floor 9

The problem with the code is that the order is not guarantee.

My code below

let startAt = this.addAreasForm.controls['startAt'].value
const name = this.addAreasForm.controls['name'].value
const newArea = {name: name}

for (let i = 1; i < (amount + 1); i++) {
  newArea.name = name + ' ' + startAt
  startAt++
  this.areasService.createArea(newArea, parentId)
    .subscribe(
      area => this.added.emit(area)
    )
}

Can e back like

Floor 2
Floor 3
Floor 1
Floor 5
Floor 4

How do you handle async api calls to guarantee sequential order?

I'm trying to create a form that allows you to create multiple resources in sequential order.

Example below

Floor 1
Floor 2
Floor 3
...
Floor 9

The problem with the code is that the order is not guarantee.

My code below

let startAt = this.addAreasForm.controls['startAt'].value
const name = this.addAreasForm.controls['name'].value
const newArea = {name: name}

for (let i = 1; i < (amount + 1); i++) {
  newArea.name = name + ' ' + startAt
  startAt++
  this.areasService.createArea(newArea, parentId)
    .subscribe(
      area => this.added.emit(area)
    )
}

Can e back like

Floor 2
Floor 3
Floor 1
Floor 5
Floor 4

How do you handle async api calls to guarantee sequential order?

Share Improve this question asked Aug 17, 2017 at 14:00 locnguyenlocnguyen 8411 gold badge12 silver badges25 bronze badges 2
  • Maybe you can concat observables inside for loop, and subscribe to a result after the loop is finished? reactivex.io/rxjs/class/es6/… – Egor Stambakio Commented Aug 17, 2017 at 14:05
  • You know, when you update the name property of the newArea object all previously set values are updated right..? Objects are reference type. Other than that i would remend inserting promises sequentially in an array and reducing them by .then() stages. – Redu Commented Aug 17, 2017 at 14:24
Add a ment  | 

2 Answers 2

Reset to default 5

You can use async / await for that purpose with the Promise resolve:

for (let i = 1; i < (amount + 1); i++) {
    await new Promise(resolve => {
        newArea.name = name + ' ' + startAt
        startAt++
        this.areasService.createArea(newArea, parentId)
            .subscribe(
                area => { 
                    this.added.emit(area);
                    resolve();
                });
        });
}

Remember to put async before your function. See this demo on StackBlitz.

You can try something like this, I don't exactly all your code from your services, but the main idea is this: In order to execute async code in order, you can build an array of promises and then to use Promise.all to take each result in the same order from the creation: Promise.all

let startAt = this.addAreasForm.controls['startAt'].value;
const name = this.addAreasForm.controls['name'].value;
const newArea = {name: name};

Keep your services into variables I don't know from where your context es.

 const areasService = this.areasService,
    added = this.added;

Make a function that create a promise for your subscribe:

function createAreaPromise(newArea, parentId) {
    return new Promise((resolve, reject) => {
        areasService.createArea(newArea, parentId)
            .subscribe(area => resolve(area));
    });
}

Than another function to build multiple an array of promises:

function buildPromises() {
    let promises = [];

    for (let i = 1; i < (amount + 1); i++) {
      newArea.name = name + ' ' + startAt
      startAt++
      promises.push(createAreaPromise(newArea, parentId));
    }

    return promises;
}

Then solve them with Promise.all, to obtain the same order from creation

let promises = buildPromises();
Promise.all(promises)
    .then(results => {
        results.forEach(result => added.emit(result));
    });

Here a live example:

function random() {
	return Math.floor(Math.random() * 5);
}

function makePromise(index) {
	return new Promise((resolve) => {
		setTimeout(() => {
			resolve(index);
		}, random() * 1000);
	});
}

function buildPromises() {
	let promises = [];
	for(let i = 0; i < 5; i++) {
		promises.push(makePromise(i));
	}

	return promises;
}

let promises = buildPromises();
Promise.all(promises)
	.then(results => {
		results.forEach(result => {
			console.log(result);
		});
	});

发布评论

评论列表(0)

  1. 暂无评论