Home > Web Front-end > JS Tutorial > Promises/A & Async await - JavaScript challenges

Promises/A & Async await - JavaScript challenges

Barbara Streisand
Release: 2024-11-04 15:02:34
Original
614 people have browsed it

Promises/A  & Async await - JavaScript challenges

You can find all the code in this post at the repo Github.


Async programming Promises/A & Async await related challenges


Implement Promises/A with Promise.finally()

class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach((callbackFn) => callbackFn(this.value));
      }
    } 

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach((callbackFn) => callbackFn(this.reason));
      }
    }

    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  handlePromiseResult(result, resolve, reject) {
    if (result instanceof MyPromise) {
      result.then(resolve, reject);
    } else {
      resolve(result);
    }
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function'
      ? onFulfilled
      : (value) => value;
    onRejected = typeof onRejected === 'function'
      ? onRejected
      : (reason) => { throw reason; };

    // return a promise
    return new MyPromise((resolve, reject) => {
      const fulfilledHandler = () => {
        queueMicrotask(() => {
          try {
            const result = onFulfilled(this.value);
            this.handlePromiseResult(result, resolve, reject);
          } catch (err) {
            reject(err);
          }
        });
      };

      const rejectedHandler = () => {
        queueMicrotask(() => {
          try {
            const result = onRejected(this.reason);
            this.handlePromiseResult(result, resolve, reject);
          } catch (err) {
            reject(err);
          }
        });
      };

      if (this.state === 'fulfilled') {
        fulfilledHandler();
      } else if (this.state === 'rejected') {
        rejectedHandler();
      } else {
        this.onFulfilledCallbacks.push(fulfilledHandler);
        this.onRejectedCallbacks.push(rejectedHandler);
      }
    });
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  finally(onFinally) {
    if (typeof onFinally !== 'function') {
      return this.then();
    }

    return this.then(
      (value) => MyPromise.resolve((onFinally()).then(() => value)),
      (reason) => MyPromise.resolve(onFinally()).then(() => { throw reason })
    );
  }

  static resolve(value) {
    return new MyPromise((resolve) => resolve(value));
  }

  static reject(reason) {
    return new MyPromise((_, reject) => reject(reason));
  }
}

// Usage example
const promise = MyPromise.resolve(1);
promise.then((value) => {
  console.log(value);
})
.then(() => {
  throw new Error('Error');
})
.catch((err) => {
  console.log(`Error catched: ${err}`);
});
Copy after login

Implement async await with generator

function asyncGenerator(generatorFunc) {
  return function (...args) {
    const generator = generatorFunc(...args);

    return new Promise((resolve, reject) => {
      function handle(iteratorResult) {
        if (iteratorResult.done) {
          resolve(iteratorResult.value);
          return;
        }

        Promise.resolve(iteratorResult.value)
          .then(
            (value) => handle(generator.next(value)),
            (err) => handle(generator.throw(err)),
          );
      }

      try {
        handle(generator.next());
      } catch (err) {
        reject(err);
      }
    });
  }
}

// Usage example
function* fetchData() {
  const data1 = yield fetch('https://jsonplaceholder.typicode.com/posts/1').then(res => res.json());
  console.log(data1);

  const data2 = yield fetch('https://jsonplaceholder.typicode.com/posts/2').then(res => res.json());
  console.log(data2);
}

// Create an async version of the generator function
const asyncFetchData = asyncGenerator(fetchData);

// Call the async function
asyncFetchData()
  .then(() => console.log('All data fetched!'))
  .catch(err => console.error('Error:', err));
Copy after login

Reference

  • 67. create your own Promise - BFE.dev
  • 123. implement Promise.prototype.finally() - BFE.dev
  • Promise - MDN
  • async function - MDN
  • Promises/A

The above is the detailed content of Promises/A & Async await - JavaScript challenges. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template