likes
comments
collection
share

我用Promise加载一张图片一、Promise基本原理 Promise是JavaScript中处理异步操作的一种方式,

作者站长头像
站长
· 阅读数 46

Promise是一种处理异步操作的方便、可靠的方式。它具有明确的状态和链式调用的特点,在JavaScript中得到了广泛的应用。掌握Promise的使用方法及其原理,有助于我们更好地理解JavaScript异步编程的本质,并提高代码的可读性和可维护性。

一、Promise基本原理

Promise是JavaScript中处理异步操作的一种方式,通过它可以将异步操作转化为同步操作,使得代码更易读、可维护。在本篇文章中,我将为您详解Promise的原理。

  1. Promise的基本概念

Promise是一个对象,它有三个状态:等待(pending)、已完成(fulfilled)和已拒绝(rejected)。当Promise对象处于等待状态时,表示异步操作正在执行;当Promise对象处于已完成状态时,表示异步操作已经成功执行,并返回了结果;当Promise对象处于已拒绝状态时,表示异步操作执行失败。

  1. Promise的基本用法

在JavaScript中,我们可以使用Promise来进行异步操作。下面是一个示例:

function asyncOperation() {
  return new Promise(function(resolve, reject) {
    // 异步操作
    setTimeout(function() {
      if (Math.random() < 0.5) {
        resolve('success');
      } else {
        reject('failure');
      }
    }, 1000);
  });
}

asyncOperation()
  .then(function(result) {
    console.log('Async operation succeeded:', result);
  })
  .catch(function(error) {
    console.error('Async operation failed:', error);
  });

在上述代码中,我们首先定义了一个asyncOperation函数,它返回一个Promise对象。在Promise对象中,我们进行了异步操作,模拟了一个耗时1秒的任务,并通过resolve和reject方法来表示异步操作的成功或失败。在Promise对象返回后,我们使用then和catch方法来处理异步操作的结果。在异步操作成功时,then方法会被调用,并传递异步操作的结果;在异步操作失败时,catch方法会被调用,并传递一个错误对象。

  1. Promise的实现原理

Promise的实现原理可以概括为以下几个步骤:

  • 创建Promise对象,并将其状态设置为等待(pending);
  • 调用异步操作,并在异步操作成功或失败时,分别调用resolve和reject方法来改变Promise对象的状态;
  • 使用then和catch方法分别处理Promise对象的成功和失败情况;
  • then和catch方法返回的是一个新的Promise对象,可以进行链式调用。

代码实现如下:

function MyPromise(fn) {
  var state = 'pending';
  var value = null;
  var callbacks = [];

  this.then = function(onFulfilled, onRejected) {
    return new MyPromise(function(resolve, reject) {
      handle({
        onFulfilled: onFulfilled || null,
        onRejected: onRejected || null,
        resolve: resolve,
        reject: reject
      });
    });
  };

  function handle(callback) {
    if (state === 'pending') {
      callbacks.push(callback);
      return;
    }

    var cb = state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;
    if (cb === null) {
      cb = state === 'fulfilled' ? callback.resolve : callback.reject;
      cb(value);
      return;
    }

    var ret;
    try {
      ret = cb(value);
      callback.resolve(ret);
    } catch (err) {
      callback.reject(err);
    }
  }

  function resolve(newValue) {
    try {
      if (newValue && typeof newValue.then === 'function') {
        newValue.then(resolve, reject);
        return;
      }
      state = 'fulfilled';
      value = newValue;
      execute();
    } catch (err) {
      reject(err);
    }
  }

  function reject(reason) {
    state = 'rejected';
    value = reason;
    execute();
  }

  function execute() {
    setTimeout(function() {
      callbacks.forEach(function(callback) {
        handle(callback);
      });
    }, 0);
  }

  fn(resolve, reject);
}

在上述代码中,我们定义了一个MyPromise函数,它接受一个函数作为参数,并返回一个新的Promise对象。在MyPromise函数内部,我们定义了state、value和callbacks变量,分别用于表示Promise对象的状态、值和回调函数。使用then方法来注册回调函数,然后定义了handle、resolve、reject和execute等内部函数,用于处理回调函数的执行和Promise对象的状态转换。

在resolve方法中,我们首先判断传入的值是否为Promise对象,如果是,则递归调用其then方法;否则,将Promise对象的状态设置为已完成(fulfilled),并将传入的值赋给value变量,最后执行execute函数来处理回调函数。在reject方法中,我们直接将Promise对象的状态设置为已拒绝(rejected),并将传入的原因赋给value变量,然后执行execute函数来处理回调函数。在execute函数中,我们通过setTimeout来将回调函数的执行推迟到下一个事件循环中,以保证Promise对象的状态已经改变。

二、用Promise加载一张图片

如何手写一个Promise来加载一张图片~~~

Promise是JavaScript中用于处理异步操作的一个对象。我们可以使用它来解决回调地狱和多个异步操作之间的协调问题。在下面的代码中,我将演示如何使用Promise来加载一张图片。

function loadImage(src) {
  return new Promise(function(resolve, reject) {
    var img = new Image();
    img.onload = function() {
      resolve(img);
    }
    img.onerror = function() {
      reject(new Error('Failed to load image: ' + src));
    }
    img.src = src;
  });
}

loadImage('https://www.towao.com/image.jpg')
  .then(function(img) {
    console.log('Image loaded successfully.');
    document.body.appendChild(img);
  })
  .catch(function(err) {
    console.error(err);
  });

在上述代码中,我们首先定义了一个loadImage方法,该方法接受一个图片的URL作为参数,并返回一个Promise对象。在该Promise对象中,我们创建了一个Image对象,并添加了它的onload和onerror事件处理函数。当图片加载成功时,我们通过resolve方法将Image对象传递给后续的then方法;当图片加载失败时,我们通过reject方法将一个Error对象传递给后续的catch方法。

接下来,我们通过调用loadImage方法来加载图片,并使用then和catch方法分别处理加载成功和失败的场景。在加载成功的情况下,我们将Image对象添加到Web页面中;在加载失败的情况下,我们输出错误信息到控制台。

通过上述代码,我们可以看出,使用Promise可以使得异步操作更加可读、可维护,并且可以更好地处理异常情况。

转载自:https://juejin.cn/post/7224302292224032826
评论
请登录