简体   繁体   English

在有或没有 jquery 的情况下使用延迟角度承诺的正确方法是什么?

[英]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.我想在 angular8 中复制它,并在组件内部打字。 I tried npm installing jquery and npm i @types/jquery.我试过 npm 安装 jquery 和 npm i @types/jquery。 I am seeing the following error with the line "d = d":我在“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.如果有一个更优雅的 angular only/javascript 方式,则不必使用 jquery,如果有另一个众所周知的标准库并且适用于我正在尝试做的事情,那么这是一个可以接受的答案。

Your example can be done with observables using the concat function.您的示例可以使用concat函数使用 observable 来完成。

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. concat 函数按照它们完成的顺序从 observable 发出值。

Observables are the preferred alternative to promises in Angular, and you can do basically everything you previously did with Promises plus much more. Observables 是 Angular 中 Promise 的首选替代品,你基本上可以做你以前用 Promises 做的所有事情,以及更多。

Promises are pull based where a value is resolved. Promise 是基于拉取的值被解析。 Observables are push based where values are emitted. Observable 是基于推送的值的发射位置。 The later allows for declarative programming where you describe how the data stream is modified.后者允许声明式编程,您可以在其中描述如何修改数据流。

Some tutorials on observables:一些关于 observables 的教程:

https://www.javascripttuts.com/introduction-to-angular-2-observables/ https://blog.logrocket.com/understanding-rxjs-observables/ https://medium.com/@kevinwkds/angular-observable-81eea33a1aab 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:如果您正在寻找使用 Promises 的方法(如标题所示),那么您可以执行以下操作:

// 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
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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