Sequential code execution in angular/ typescript

后端 未结 7 2155
醉梦人生
醉梦人生 2021-01-01 06:02

How can I make my code run sequentially? For example,

  1. If I have a for loop which gets some data from a service, I want the n+1 iteration to run

相关标签:
7条回答
  • 2021-01-01 06:02

    You could wrap each iteration in a Promise and await it:

    async function someMethod() {
        for (var i = 0; i < 5; i++) {
            await new Promise(resolve => {
                setTimeout(()=> {
                    console.log('This is iteration ' + i); 
                    resolve();
                }, 500);
            });
        }
        console.log ('print me only after all iterations');
    }
    someMethod();
    
    0 讨论(0)
  • 2021-01-01 06:03

    You can do it with Promise.

    someMethod() : Promise<any> {
    
     return new Promise((resolve) => {
      for ( var i = 0; i < someLength; i++) {
            // get some data
            this.dataService.get(i).subscribe(data => {
                // do something with the data
            }); 
    
    if(i==someLength-1){resolve();}
        }
    
    
    }).then(()=>{ 
    
    
        // 
        console.log ('print me only after all iterations');
    
        // ....
        // some more lines of code
    })
    }
    
    0 讨论(0)
  • 2021-01-01 06:09

    Are you looking for something like this? (plunker)

    export class App {
      name:string;
      constructor() {
        this.name = `Angular! v${VERSION.full}`;
    
        this.someMethod();
      }
    
      doTimeout(currentIndex:int){
        return new Promise(resolve => {
          setTimeout(()=> {
            console.log("This is iteration " + currentIndex);
            resolve();
          },500);
        });
      }
    
      async someMethod() {
        for(let i=0;i<5;i++){
          await this.doTimeout(i);
        }
        // I want to execute this line of code only after the 
        // for loop has completed all iterations. 
        console.log ('print me only after all iterations'); 
    
        // ....
        // some more lines of code
      }
    }
    

    Sources: What is the JavaScipt Version of sleep? and Combination of async function + await + setTimeout

    0 讨论(0)
  • 2021-01-01 06:09

    I suggest adapting it to use the zip "combining operator" from rxjs:

    http://reactivex.io/documentation/operators/zip.html

    EDIT: here is an example: https://www.learnrxjs.io/operators/combination/zip.html

    Although in your case you would have to pass it as an array probably ( zipArray).

    0 讨论(0)
  • 2021-01-01 06:14

    As Javascript is a single thread language, it is hard to do what exactly you want to achieve unless you use Promise or other callback architecture.

    There are many ways to achieve it through PROMISEs. Here, I'll show you how can you achieve the same using advance JavaScript concept called Async & Await in Angular framework.

    Please note there are many ways with Promise but my intention is to introduce you to new async & await concept where you don't need to chain the callback for success and reject methods.

    DEMO : https://plnkr.co/edit/16k66yRjXLPwTM50kYNS

    export class App {
      name:string;
      constructor() {
        this.name = `Angular! v${VERSION.full}`;
        this.someMethod(); 
      }
    
     const someMethod_Promise = () => {
      return new Promise((resolve,reject)=>{
         for ( var i = 0; i < 5; i++) {
           console.log('printing value of i ' + i);
            if(i==4)   // real condition
             resolve(true);
         } 
      })
     }
    
     const someMethod = async()=>{
       let result= await this.someMethod_Promise();
       if(result){
          console.log ('print me only after all iterations'); 
       }
     }
    }
    
    0 讨论(0)
  • 2021-01-01 06:25

    Promise based solution:

    Promise.all() takes an array of promises and fires them all at the same time. Then once all of the promises resolve it will run the callback.

    let dataService = {
      get: function(i) {
        return new Promise((resolve, reject) => {
          setTimeout(resolve, 100, i);
        });
      }
    }
    
    let promises = [];
    
    for (var i = 0; i < 3; i++) {
        // get some data
        promises.push(dataService.get(i));
    }
    
    Promise.all(promises).then(values => { 
      console.log ('print me only after all iterations');
      console.log(values); 
    });
    

    Working sample: http://jsbin.com/ruqiwoxono/edit?js,console

    Promise.all docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

    Rxjs based solution:

    forkJoin basically does the same thing as Promise.all() but for observables

    let dataService = {
      get: function(i) {
        return Rx.Observable.of(i);
      }
    }
    
    let observables = [];
    
    for (var i = 0; i < 3; i++) {
        // get some data
        observables.push(dataService.get(i));
    }
    
    
    const example = Rx.Observable.forkJoin(observables);
    
    
    const subscribe = example.subscribe(values => {
      console.log ('print me only after all iterations');
      console.log(values); 
    });
    

    Working sample: http://jsbin.com/jolotuyoxa/edit?js,console

    Rxjs forkjoin docs: https://www.learnrxjs.io/operators/combination/forkjoin.html

    0 讨论(0)
提交回复
热议问题