资讯专栏INFORMATION COLUMN

Promise的简单实现

Hwg / 614人阅读

摘要:本篇文章通过构建一个简单的对象来了解如何做到异步获得数据。的简单实现首先,我们要知道实际上是一个对象,当我们运行下面的代码可以发现返回。

本篇文章通过构建一个简单的Promise对象来了解如何做到异步获得数据。

使用方法
const fetch = function(url) {
  return new Promise((resolve, reject) => {
    request((error, apiResponse) => {
      if (error) {
         //返回为error的时候,调用reject函数
        reject(error)
      }
      // 有数据返回的时候,调用resolve
      resolve(apiResponse)
    })
  })
}

这个fetch()的方法返回了一个Promise对象,接着我们就可以用then来对获得的数据进行处理,catch来捕获可能的错误。

Promise的简单实现

首先,我们要知道Promise实际上是一个对象,当我们运行下面的代码可以发现返回true。

console.log(typeof new Promise((resolve, reject) => {}) === "object") // true

接着要构建一个Promise类,来生成Promise Object。

思路:

在constructor 里面传入executionFunction, 然后将onResolve,onReject映射到里面,then主要做一件事情,就是将onResolve的函数收集起来,在this.onResolve里面一起调用,每次返回的值都覆盖前一次的。

说的什么玩意儿,眼见为实下面来看一下代码:

class PromiseSimple{
    constructor(executionFunction) {
        this.promiseChain = [];
        this.onResolve = this.onResolve.bind(this)
        this.onReject = this.onReject.bind(this)
        this.handleError = () => {}
        // 外界传入的函数我们将其定义为executionFunction,将里面
        // 的onResolve onReject 映射到this.onResolve, this.onReject
        executionFunction(this.onResolve, this.onReject)
    }
    then(onResolve) {
        // 收集状态成功的时候的回调函数
        this.promiseChain.push(onResolve)
        return this
    } 
    catch(onReject) {
        this.handleError = onReject
        return this
    }
    onResolve(value) {
    var storedValue = value;
    try {
        // 在resolve里面执行
        this.promiseChain.forEach((executePromise) => {
            storedValue = executePromise(storedValue)
        })
    } catch(error){
        this.promiseChain = [];
        this.onReject(error)
    }
    }
    onReject(error) {
        this.handleError(error)
    }
}
梳理一下,其实只要记住其中两点:

1、这个对象有四个方法then catch onResolve onReject,它们的作用分别是

then

用来收集有数据的时候的回调函数,放在this.promiseChain里,注意这里要返回this

对象才能实现链式调用

catch

用来处理出现的error,注意这里要返回this对象实现链式调用

onResolve

依次执行then里面收集的回调函数,并且将回调函数的返回值在作为参数传给下一个回调函数

onReject

用来处理出现的error

2、then catch 必须要返回this,才能实现链式调用

这样我们一个简单的Promise 对象就做好了

下面可以用这个来玩一玩

class PromiseSimple {
  constructor(executionFunction) {
    this.promiseChain = [];
    this.handleError = () => {};

    this.onResolve = this.onResolve.bind(this);
    this.onReject = this.onReject.bind(this);

    executionFunction(this.onResolve, this.onReject);
  }

  then(onResolve) {
    this.promiseChain.push(onResolve);

    return this;
  }

  catch(handleError) {
    this.handleError = handleError;

    return this;
  }

  onResolve(value) {
    let storedValue = value;

    try {
      this.promiseChain.forEach((nextFunction) => {
         storedValue = nextFunction(storedValue);
      });
    } catch (error) {
      this.promiseChain = [];

      this.onReject(error);
    }
  }

  onReject(error) {
    this.handleError(error);
  }
}

fakeApiBackend = () => {
  const user = {
    username: "treyhuffine",
    favoriteNumber: 42,
    profile: "https://gitconnected.com/treyhuffine"
  };

  // Introduce a randomizer to simulate the
  // the probability of encountering an error
  if (Math.random() > .05) {
    return user;
  } else {
    const error = {
      statusCode: 404,
      message: "Could not find user",
      error: "Not Found",
    };
    
    return error;
  }
};

// Assume this is your AJAX library. Almost all newer
// ones return a Promise Object
const makeApiCall = () => {
  return new PromiseSimple((resolve, reject) => {
    // Use a timeout to simulate the network delay waiting for the response.
    // This is THE reason you use a promise. It waits for the API to respond
    // and after received, it executes code in the `then()` blocks in order.
    // If it executed is immediately, there would be no data.
    setTimeout(() => {
      const apiResponse = fakeApiBackend();

      if (apiResponse instanceof  Error) {
        reject(apiResponse);
      } else {
        resolve(apiResponse);
      }
    }, 5000);
  });
};

makeApiCall()
  .then((user) => {
    console.log("In the first .then()");
  
    return user;
  })
  .then((user) => {
    console.log(`User ${user.username}"s favorite number is ${user.favoriteNumber}`);
  
    return user;
  })
  .then((user) => {
    console.log("The previous .then() told you the favoriteNumber")
  
    return user.profile;
  })
  .then((profile) => {
    console.log(`The profile URL is ${profile}`);
  })
  .then(() => {
    console.log("This is the last then()");
  })
  .catch((error) => {
    console.log(error.message);
  });

参考文档:
https://medium.com/gitconnect...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88959.html

相关文章

  • JavaScript Promise启示录

    摘要:近几年随着开发模式的逐渐成熟,规范顺势而生,其中就包括提出了规范,完全改变了异步编程的写法,让异步编程变得十分的易于理解。最后,是如此的优雅但也只是解决了回调的深层嵌套的问题,真正简化异步编程的还是,在端,建议考虑。 本篇,简单实现一个promise,主要普及promise的用法。 一直以来,JavaScript处理异步都是以callback的方式,在前端开发领域callback机制...

    Juven 评论0 收藏0
  • 简单实现 ES6 Promise

    摘要:实现的一个简单的如果有错误的地方,希望大家能够不吝赐教仅实现及方法最下方有完整代码开始一个对象接收的是一个这个接收两个参数当我们在内执行或的时候,就会调用内定义的和函数然后,和函数会改变的状态所以它应该是像下面这样的保存值记录状态为,为,为 实现的一个简单的ES6 Promise(如果有错误的地方,希望大家能够不吝赐教) 仅实现Promise及.then方法最下方有完整代码 开始 一个...

    zhichangterry 评论0 收藏0
  • Promise——从阅读文档到简单实现(二)

    摘要:在和方法执行的时候订阅事件,将自己的回调函数绑定到事件上,属性是发布者,一旦它的值发生改变就发布事件,执行回调函数。实现和方法的回调函数都是,当满足条件对象状态改变时,这些回调会被放入队列。所以我需要在某个变为时,删除它们绑定的回调函数。 前言 按照文档说明简单地实现 ES6 Promise的各个方法并不难,但是Promise的一些特殊需求实现起来并不简单,我首先提出一些不好实现或者容...

    dinfer 评论0 收藏0
  • Promise 简单实现

    摘要:简单实现前言你可能知道,的任务执行的模式有两种同步和异步。你已经实现了方法方法是一个很好用的方法。感兴趣的朋友可以自行去研究哈附上代码完整的实现个人博客链接 Promise 简单实现 前言 你可能知道,javascript 的任务执行的模式有两种:同步和异步。 异步模式非常重要,在浏览器端,耗时很长的操作(例如 ajax 请求)都应该异步执行,避免浏览器失去响应。 在异步模式编程中,我...

    dayday_up 评论0 收藏0
  • [ JS 进阶 ] 异步编程 promise模式 简单实现

    摘要:为了降低异步编程的复杂性,所以。难理解请参考的误区以及实践异步编程的模式异步编程的种方法 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多或少用到,最典型的就是异步ajax,发送异步请求,绑定回调函数,请求响应之后调用指定的回调函数,没有阻塞其他代码的执行。还有像setTimeout方法同样也是异步执行回调的方法。 如果对异步编程...

    svtter 评论0 收藏0
  • [转载·JS] JavaScript Promise启示录

    摘要:近几年随着开发模式的逐渐成熟,规范顺势而生,其中就包括提出了规范,完全改变了异步编程的写法,让异步编程变得十分的易于理解。最后,是如此的优雅但也只是解决了回调的深层嵌套的问题,真正简化异步编程的还是,在端,建议考虑。 前段时间频频看到Promise这个词,今天发现腾讯AlloyTeam写得这篇很赞,遂转之。 原文链接 本篇,主要普及promise的用法。 一直以来,JavaScrip...

    Lyux 评论0 收藏0

发表评论

0条评论

Hwg

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<