Promise和Promise.all原理和实现 你知道吗

JavaScript Promise 是一种用于处理异步操作的对象,它可以让你更加优雅和简单地处理异步操作的结果。Promise.all 则是一个可以将多个 Promise 合并为一个的工具,可以实现并行处理多个异步操作的结果。下面我们来介绍 Promise 和 Promise.all 的原理及实现。

Promise 的原理及实现

Promise 的实现基于回调函数。它提供了一种链式调用的语法,使得我们可以更加优雅地处理异步操作的结果。在 Promise 的内部,它会将回调函数分为两种情况:成功回调和失败回调。当异步操作成功时,Promise 会调用成功回调并传入成功结果;当异步操作失败时,Promise 会调用失败回调并传入失败原因。

Promise 的核心是 then 方法和 catch 方法。then 方法用于处理成功回调,catch 方法用于处理失败回调。当 Promise 成功完成时,会调用 then 方法;当 Promise 失败时,会调用 catch 方法。在 then 和 catch 方法中,我们可以根据操作的结果来执行相应的代码。

下面是一个简单的 Promise 实现示例:

class MyPromise {
    
    
  constructor(callback) {
    
    
    this.status = 'pending';
    this.value = null;
    this.error = null;

    const resolve = value => {
    
    
      if (this.status === 'pending') {
    
    
        this.status = 'resolved';
        this.value = value;
      }
    };

    const reject = error => {
    
    
      if (this.status === 'pending') {
    
    
        this.status = 'rejected';
        this.error = error;
      }
    };

    try {
    
    
      callback(resolve, reject);
    } catch (error) {
    
    
      reject(error);
    }
  }

  then(onResolved, onRejected) {
    
    
    if (this.status === 'resolved') {
    
    
      return new MyPromise(resolve => {
    
    
        try {
    
    
          const result = onResolved(this.value);
          resolve(result);
        } catch (error) {
    
    
          reject(error);
        }
      });
    } else if (this.status === 'rejected') {
    
    
      return new MyPromise((resolve, reject) => {
    
    
        try {
    
    
          const result = onRejected(this.error);
          resolve(result);
        } catch (error) {
    
    
          reject(error);
        }
      });
    }
  }

  catch(onRejected) {
    
    
    if (this.status === 'rejected') {
    
    
      return new MyPromise(resolve => {
    
    
        try {
    
    
          const result = onRejected(this.error);
          resolve(result);
        } catch (error) {
    
    
          reject(error);
        }
      });
    }
  }
}

在上述代码中,我们定义了一个 MyPromise 类,它接受一个回调函数作为参数,并提供了 then 方法和 catch 方法。在构造函数中,我们定义了 resolve 函数和 reject 函数,当异步操作成功时,调用 resolve 函数并传入成功结果,当异步操作失败时,调用 reject 函数并传入错误信息。在 then 方法和 catch 方法中,我们通过 if 语句来判断 Promise 的状态,并根据状态来执行相应的回调函数。

Promise.all 的原理

Promise.all 的原理是将多个 Promise 对象包装成一个新的 Promise 对象,当所有的 Promise 对象都成功完成时,该新的 Promise 对象才会成功完成,并且将所有的成功结果按顺序放入一个数组中作为该新的 Promise 对象的成功结果;当其中任意一个 Promise 对象失败时,该新的 Promise 对象就会失败,并且将第一个失败的 Promise 对象的失败原因作为该新的 Promise 对象的失败原因。

下面是一个简单的 Promise.all 实现示例:

function myPromiseAll(promises) {
    
    
  return new Promise((resolve, reject) => {
    
    
    const results = new Array(promises.length);
    let count = 0;

    promises.forEach((promise, index) => {
    
    
      promise.then(result => {
    
    
        results[index] = result;
        count++;

        if (count === promises.length) {
    
    
          resolve(results);
        }
      }).catch(error => {
    
    
        reject(error);
      });
    });
  });
}

在上述代码中,我们定义了一个 myPromiseAll 函数,它接受一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。在该函数内部,我们定义了一个 results 数组来保存所有 Promise 对象的结果,定义了一个 count 变量来记录已完成的 Promise 对象个数。

然后,我们通过 forEach 方法遍历所有的 Promise 对象,并为每个 Promise 对象绑定成功回调和失败回调。当一个 Promise 对象成功时,将其成功结果放入 results 数组中,并增加 count 变量的值。当 count 的值等于 Promise 对象数组的长度时,说明所有的 Promise 对象都已完成,此时将 results 数组作为新的 Promise 对象的成功结果,调用 resolve 方法并传入该数组。当一个 Promise 对象失败时,直接调用 reject 方法并传入该 Promise 对象的失败原因。

使用 Promise.all 可以方便地处理多个异步操作,并行获取多个异步操作的结果。例如:

const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 2000));
const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 3000));

Promise.all([promise1, promise2, promise3]).then(results => {
    
    
  console.log(results); // [1, 2, 3]
}).catch(error => {
    
    
  console.log(error);
});

在上述代码中,我们创建了三个 Promise 对象,分别延迟 1 秒、2 秒和 3 秒后返回不同的结果。然后,我们使用 Promise.all 方法将这三个 Promise 对象合并成一个,并在所有 Promise 对象都成功完成后输出它们的结果。在本例中,由于三个 Promise 对象都成功完成,因此输出了一个包含它们的结果的数组。

猜你喜欢

转载自blog.csdn.net/qq_29669259/article/details/130272458