简体   繁体   中英

What is the right way to use deferred angular promises with or without jquery?

Without angular or typescript, I have the following code:

let queue = [
    function () { 
      let waitingTime = 0 ;
      setTimeout(function () { console.log("a - " + Date.now()); }, waitingTime); },
    function () { 
      let waitingTime = 2500 ;
      setTimeout(function () { console.log("b - " + Date.now()); }, waitingTime); },
    function () { 
      let waitingTime = 5000 ;
      setTimeout(function () { console.log("c - " + Date.now()); }, waitingTime); }
];

function SerialCall(queue) {
    var d = $.Deferred().resolve();
    while (queue.length > 0) {
        d = d.then(queue.shift()); // you don't need the `.done`
    }
}

SerialCall(queue);

I want to replicate this in angular8 and typesript inside of a component. I tried npm installing jquery and npm i @types/jquery. I am seeing the following error with the line "d = d":

(local var) d: JQuery.Deferred<any, any, any>
Type 'PromiseBase<never, never, never, never, never, never, never, never, never, never, never, never>' is missing the following properties from type 'Deferred<any, any, any>': notify, notifyWith, reject, rejectWith, and 2 more.ts(2740)

What is the correct way to do what I am trying to do? (execute the first function in queue, after it completes, do the second, then the third). Does not have to use jquery if there is an angular only/javascript way that is more elegant, if there is another standard library for this that is well known and works for what I am trying to do, that is an acceptable answer.

Your example can be done with observables using the concat function.

const queue = [
   defer(() => of(new Date()).pipe(delay(0)),
   defer(() => of(new Date()).pipe(delay(2500)),
   defer(() => of(new Date()).pipe(delay(5000))
];

concat(...queue).subscribe(console.log);

The concat functions emits values from observables in the order they are completed.

Observables are the preferred alternative to promises in Angular, and you can do basically everything you previously did with Promises plus much more.

Promises are pull based where a value is resolved. Observables are push based where values are emitted. The later allows for declarative programming where you describe how the data stream is modified.

Some tutorials on observables:

https://www.javascripttuts.com/introduction-to-angular-2-observables/ https://blog.logrocket.com/understanding-rxjs-observables/ https://medium.com/@kevinwkds/angular-observable-81eea33a1aab

If you are looking for an approach using Promises (as the title suggest) then you can do the following:

// Let's stick to your original functions array
const queue = [
    function () { 
      let waitingTime = 0 ;
      setTimeout(function () { console.log("a - " + Date.now()); }, waitingTime); },
    function () { 
      let waitingTime = 2500 ;
      setTimeout(function () { console.log("b - " + Date.now()); }, waitingTime); },
    function () { 
      let waitingTime = 5000 ;
      setTimeout(function () { console.log("c - " + Date.now()); }, waitingTime); }
];


// you'll need this for the .reduce call
const starterPromise = Promise.resolve(null);

  // Our Async wrapper
  function asyncRunner(fn) {
    return (new Promise(resolve => { resolve(fn()) }));
  }

// and finally the reducer
await queue.reduce(
    (p, fn) => p.then(() => asyncRunner(fn)),
    starterPromise
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM