手写Promise

总结一下 Promise,怎么使用,如何手写 promise Promise 是 JavaScript 中的一个异步编程解决方案,它代表了一个最终可能完成(或失败)及其结果值的异步操作。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise 一旦从 pending 状态变为 fulfilled 或 rejected 状态,状态就不会再改变,即 Promise 的状态是不可逆的。 阅读详情

Promise是ES6中处理异步操作的重要工具,它的实现原理让我们的代码更加简洁高效。本文将为你揭开ES6 Promise的神秘面纱,让你彻底了解其实现原理,同时展示如何运用Promise优化代码。

什么是Promise?

Promise是一种用于处理异步操作的对象,表示一个异步操作的最终完成或失败。Promise有三种状态:Pending(进行中)、Fulfilled(已成功)、Rejected(已失败)。一旦Promise的状态从Pending变为Fulfilled或Rejected,它就不会再改变。

Promise的实现原理

Promise的实现原理涉及了一些JavaScript的核心概念,包括闭包、回调函数和事件循环。让我们逐步了解Promise的实现细节:

1. 构造函数

首先,我们需要一个Promise构造函数,它接受一个函数作为参数,该函数有两个参数:resolve和reject。这个函数通常称为执行器函数。

function Promise(executor) {
  // ...
}
2. 状态管理

Promise需要管理自己的状态(Pending、Fulfilled、Rejected)。我们可以使用闭包来保存状态,并提供方法来改变状态。

function Promise(executor) {
  let state = 'pending';
  let value = null;

  function resolve(result) {
    state = 'fulfilled';
    value = result;
  }

  function reject(error) {
    state = 'rejected';
    value = error;
  }
}
3. then方法

Promise对象上有一个then方法,它接受两个回调函数作为参数,分别用于处理Promise状态变为Fulfilled和Rejected时的情况。

function Promise(executor) {
  // ...

  this.then = function (onFulfilled, onRejected) {
    // ...
  };
}
4. 异步操作

Promise需要支持异步操作,所以我们需要使用事件循环来处理异步任务,确保then方法中的回调在适当的时间执行。

function Promise(executor) {
  // ...

  setTimeout(function () {
    // 执行executor函数
    executor(resolve, reject);
  }, 0);
}
5. 处理链式调用

最后,我们需要处理链式调用。当then方法被调用时,它应该返回一个新的Promise对象,以支持链式调用。

function Promise(executor) {
  // ...

  this.then = function (onFulfilled, onRejected) {
    // 返回新的Promise对象
    return new Promise(function (resolve, reject) {
      // ...
    });
  };
}

到这里就实现了Promise的基本轮廓。完整代码如下:

function Promise(executor) {
  let state = 'pending';
  let value = null;

  function resolve(result) {
    if (state === 'pending') {
      state = 'fulfilled';
      value = result;
    }
  }

  function reject(error) {
    if (state === 'pending') {
      state = 'rejected';
      value = error;
    }
  }

  this.then = function (onFulfilled, onRejected) {
    if (state === 'fulfilled') {
      onFulfilled(value);
    } else if (state === 'rejected') {
      onRejected(value);
    }
  };

  // 执行executor函数
  executor(resolve, reject);
}

我们测试上面的方法:

// 示例用法
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功的结果');
    // 或者
    // reject('失败的原因');
  }, 1000);
});

myPromise.then(
  result => {
    console.log('成功:', result);
  },
  error => {
    console.error('失败:', error);
  }
);
6.实现all方法
function PromiseAll(promises) {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promises)) {
      reject(new TypeError('参数必须是一个 Promise 数组'));
      return;
    }

    const results = new Array(promises.length);
    let completedPromises = 0;

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

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

// 示例用法
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

PromiseAll([promise1, promise2, promise3])
  .then((results) => {
    console.log('全部成功:', results); // 输出 [1, 2, 3]
  })
  .catch((error) => {
    console.error('出错:', error);
  });

总结

Promise是一项强大的工具,它使异步编程更加清晰和可控。通过理解Promise状态和回调的概念,并掌握示例代码中的使用方式,我们可以更好地运用Promise来提升代码的可读性和性能。快来试试吧!

手写实现promise以及promise.all和promise.race 之前写的一个promise太多了,面试写下来的话。。。。emmm,所以在复习时又写一个简单的。 promise class Promsie { constructor(fn) { //三个状态 this.status = 'pending', this.resolve = undefined; this.reject = undefined; let resolve = value => { 阅读详情

相关推荐

promise应用及手写promise

Promise.all()接收一个Promise[], 返回一个Promise实例,当所有的Promise执行完毕且都是fullfilled状态时,该实例的状态才会变成fullfilled, 只要队列中有一个实例的状态是rejected,那么该实例的状态也会变成rejecte。如果Promise队列中所有的实例状态都是fullfilled,那么Promise.all()返回的是实例状态就会变成fullfilled,并且then()的参数是一个数组,按照顺序防止的队列中每个Promise成功后的结果。

m0_38066007的博客 647

【JavaScript】手写Promise

面试中经常会被问到你会手写Promise吗?本文带你手撸Promsie

编码世界 5491

手写 Promise 的实现

手写 Promise 的实现

qq_39454432的博客 1124

手写Promise代码

【代码】手写Promise代码。

weixin_45980065的博客 458

INS/伪距组合导航(2)

伪距惯导组合导航

u014430081的博客 828

vasp-自旋轨道耦合(SOC)计算步骤

在VASP中执行自旋轨道耦合(SOC)计算,具体的计算步骤如下: 结构优化获取CONTCAR文件 自洽计算(collinear normal VASP calculations)获取IBZKPT,CHGCAR和WAVECAR文件。 SCF+SOC计算,在此步骤中,将步骤2中的IBZKPT复制为KPOINTS,以便两个步骤具有相同的k网格,因此可以读取步骤2中的CHGCAR和WAVECAR文件。 能带结构计算,在此步骤中,将KPOINTS改为高对称点,读取步骤3中的CHGCAR和WAVECAR文件。

懒散的鱼与消失的猫 3万+

手写promise

前几天在看知乎的时候,无意间发现了一道面试题,手写promise,因为没研究过promise的实现,所以对这个问题也是一脸懵逼,忍不住就研究了一下。 try { module.exports = Promise } catch (e) {} function Promise(executor) { var self = this self.status = 'pendi...

GuoZebin的博客 513

“迎圣诞,拿大奖” 活动赛题 Web-SQLi

1. php中sprintf()函数漏洞原理及其利用; 2. mysql盲注语法及python脚本; 3. sqlmap的需要进一步学习;

qq_34106499的博客 674

手写Promise A+

小试牛刀 初步实现Promise: 1.实现三种状态:‘pending’, ‘fulfilled’, ‘rejected’ 2.能够实现then方法两种回调函数的处理 //promise.js class Promise{ constructor(excutorCallBack){ this.status = 'pending'; this.value = undefined;...

杨兴元的博客 2441

从零到一:树莓派OpenWrt squashfs固件扩容背后的文件系统魔法

本文深入解析树莓派OpenWrt系统中squashfs固件的扩容原理与操作。通过理解squashfs与overlayfs的协同机制,掌握分区调整和文件系统扩容技巧,解决存储空间限制问题,提升设备可用性。

hadoop5ranger的博客 1037

运维与软件实施课表

运维与软件实施课表 课程 章节编号 章节 课程地址 软件及操作系统基础 ch01 软件及操作系统基础01 实施、运维工程师基本技能:https://blog.youkuaiyun.com/qq_28189423/article/details/82700539 老毛桃制作winPE镜像:https://blog.youkuaiyun.com/qq_2818942...

Mr.O~的博客 1万+

【手写Promise】史上最最最详细的手写Promise教程

转载自https://yq.aliyun.com/articles/613412 class Promise{ constructor(executor){ this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; let resolve = va

Anles的博客 3769

Win11只读模式无法关闭的终极解决方案

通过以上方法,我们应该能够解决Windows 11中文件夹无法取消只读状态的问题。如果问题仍然存在,请确保你的账户具有足够的权限来修改文件夹属性,并考虑是否有其他安全软件或策略阻止了权限更改。在操作过程中,请务必小心谨慎,避免误操作导致数据丢失或系统损坏。希望本文能够帮助到大家!

mmoo_python的博客 1万+

方法 手写promise_手写源码系列二——Promise相关方法

欢迎关注微信公众号——“较真的前端”,里面有更多前端面试题和解答。手写Promise相关方法Promise是面试中经常遇到的,如果面试中面试官问你Promise.all()怎么用,那你面试的岗位差不多是高级前端开发的岗位,但如果让你手写一个Promise.all()那你面试的岗位应该就是资深/专家前端开发的岗位了上期回顾上期我们实现了函数的call()、bind()、apply()方法。Promi...

weixin_39611510的博客 127

# 多用户 JupyterHub 配置教程(通用 Linux 服务器版)

以上即是通用 Linux 服务器上的多用户 JupyterHub 实战配置。从安装认证与 Spawner 选择自动创建系统用户到反代与运维,覆盖了小团队到中等规模的主流场景。根据团队增长与合规要求,你可以进一步引入、统一身份源(LDAP/OAuth2/Keycloak)与资源配额治理,平滑演进到企业级部署。

数字化老司机 1289

【史上最全面esp32教程】网络篇和tcp/ip的使用

ESP32史上最全面wifi和tcp/ip连接及示例程序

m0_62599305的博客 9522

方法 手写promise_JS探索-手写Promise

无意间在知乎上刷到Monad这个概念,去了解了一下,前端的Promise就是一种Monad模式,所以试着学习一下手写一个Promise.本文内容主要参考于只会用?一起来手写一个合乎规范的Promise​www.jianshu.comPromise是什么所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可...

weixin_42516657的博客 208

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

面试官:手写个 Promise 给我看看

本文详解如何手写 Promise,帮助前端开发者掌握异步编程核心原理。文章首先通过"煮开水→泡咖啡"的示例对比回调地狱和 Promise 链式调用的区别,说明 Promise 的核心价值。随后提供完整的 Promise 实现代码,包含状态管理、resolve/reject 逻辑和 then 方法实现。重点拆解了 Promise 的 5 个关键步骤:创建 Promise 时初始化状态、定义回调函数、执行异步操作;调用 then 方法时注册回调;以及异步操作完成后触发回调的完整流程。通过生活

前端圈边缘选手,擅长把 UI 稿 “翻译” 成代码,也擅长在 console.log 里写 “求救信号”。日常状态:要么在调像素级对齐,要么在查 “为什么这个样式只在我电脑上生效”。博客不搞高深理论,只唠实在干货~ 979

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Promise基本使用以及手写源码

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,等Promise执行完,才会执行里面的东西,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。Promise有以下两个特点。

m0_74079648的博客 1736

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

手写Promise的基本实现 (超详细)

手写Promise的基本实现 (超详细) 面试必备! 本文带大家实现一个基本的 promise 过多的边界情况就不在考虐,理解主要实现过程以及逻辑即可 对于一个个出现的问题我会逐步分析原因以及对应的解决思路

qq_48554377的博客 8721

Promise高频手写面试题

Promise 高频手写

aixinalei的博客 1356

Promise详细知识点(内含手写Promise)

promise相关知识和手写promise

ixxoic的博客 1370
上一篇: git的基本概念
下一篇: ES14新特性揭秘,对前端开发有哪些影响?
前端大师兄
博客等级 码龄16年 32粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值