关键词:
前言
从事前端的朋友或多或少的接触过Promise,当代码中回调函数层级过多你就会发现Promise异步编程的魅力,相信此文一定能帮你排忧解惑!
Promise概念
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一
或许是笔者理解能力有限,对官方术语怎么也感受不到亲切,下面我来用通俗易懂的语言解释下:
Promise是一个包含三种状态的对象(pending、fulfilled、rejected),可以链式的处理异步请求(then方法)并能很好地处理异常问题,是解决回调地狱的良好方案之一。
回调函数处理多层异步示例
$.ajax( url: url1, success: function(rsp) $.ajax( url: url2, success: function(rsp) $.ajax( url: url3, success: function(rsp) //do sth , error: function(error) ); , error: function(error) ); , error: function(error) );
将promise封装在$.ajax中
$.ajax = function(config) return new Promise(function(resolve, reject) //1省略... xmlhttp.onreadystatechange = function() if(xmlhttp.status==200) resolve(rspData); else reject(xmlhttp.statusText); ; //2省略... ) $.ajax(url: url1).then(function(val) return $.ajax(url: val.url) ).then(function(val) return $.ajax(url: val.url) ).catch(function(err) console.log(err);
封装好的Promise处理异步可读性可维护性以及代码美观度不言而喻
Promise API
‘new‘ Promise
//pending状态的promise var promise = new Promise(function(resolve, reject) //do sth ) //fulfilled状态的promise var promise = Promise.resolve(1).then(function resolve(value)console.log(value)); // var promise = new Promise(function(resolve)resolve(1)) //rejected状态的promise var promise = Promise.reject(new Error(‘error‘)).catch(function(error)console.error(error)); // var promise = new Promise(function(resolve,reject)resolve(new Error(‘error‘)))
Promise.prototype.then
Promise#then
promise.then(onFulfilled, onRejected)
返回一个新的promise。这里经常会有一个疑问:为什么不返回原来的promise,个人是这样认为的,若返回同一个promise则状态不一致,promise规范说明当pending至fulfilled/rejected时状态确定后不能再改变。
Promise.prototype.catch
Promise#catch promise.catch(function(error) throw new Error(error); )
注意:IE8及以下版本会出现 identifier not found 的语法错误,可将点标记法改为中括号标记法
promise[‘catch‘](function(error) throw new Error(error); )
rejected状态的promise抛出异常
相当于
promise.then(undefined, onRejected)
then & catch 结合示例
promise.then(function f1(value) //do sth 1 ).then(function f2(value) //do sth 2 ).then(function f3(value) //do sth 3 ).catch(function(error) console.log(error); )
Promise.prototype.finally
promise.finally(onFinally)
返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行
Promise.all
promise.all([promise1, promise2, promise3]).then(resolve);
示例
// `delay`毫秒后执行resolve function timerPromisefy(delay) return new Promise(function (resolve) setTimeout(function () resolve(delay); , delay); ); var startDate = Date.now(); // 所有promise变为resolve后程序退出 Promise.all([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (values) console.log(Date.now() - startDate + ‘ms‘); // 约128ms console.log(values); // [1,32,64,128] );
在接收到所有的对象promise都变为 FulFilled 返回一个resolve(array),或者 某一个promise对象变成Rejected 状态返回resolve(err)
传递给 Promise.all 的promise并不是一个个的顺序执行的,而是同时开始、并行执行的。
Promise.race
promise.race([promise1, promise2]).then(resolve, reject)
示例
// `delay`毫秒后执行resolve function timerPromisefy(delay) return new Promise(function (resolve) setTimeout(function () resolve(delay); , delay); ); // 任何一个promise变为resolve或reject 的话程序就停止运行 Promise.race([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (value) console.log(value); // => 1 );
只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
Promise polyfill & Test
promise-polyfill.js
学习完Promise后,必定要重写Promise,后续遇到浏览器环境不支持也可有的放矢
代码如下
/** * @author chenchangyuan * @date 2019-02-23 * */ function Promise(executor) if(typeof executor !== ‘function‘) throw new Error(‘executor is not a function‘); var self = this; self.state = ‘pending‘;//pending fulfilled rejected self.value = null; self.reason = null; self.callbackResolveFn = []; self.callbackRejectFn = []; function resolve(value) if(self.state === ‘pending‘) self.state = ‘fulfilled‘; self.value = value; self.callbackResolveFn.forEach(function(fn) fn(); ); function reject(reason) if(self.state === ‘pending‘) self.state = ‘rejected‘; self.reason = reason; self.callbackRejectFn.forEach(function(fn) fn(); ); try executor(resolve, reject); catch(err) reject(err); //回溯函数 function resolvePromise(promise, x, resolve, reject) if(promise === x) return reject(new TypeError(‘循环引用‘)); var flag = false; if(x !== null && (typeof x === ‘object‘ || typeof x === ‘function‘)) try var then = x.then; if(typeof then === ‘function‘) then.call(x, function(val) if(flag) return; flag = true; resolvePromise(promise, val, resolve, reject); , function(err) if(flag) return; flag = true; reject(err); ); else resolve(x); catch(err) if(flag) return; flag = true; reject(err); else resolve(x); //返回一个新的promise(pending:push(fn),fulfilled:resolve(val),rejected:reject(reason)) Promise.prototype.then = function(onFulfilled, onRejected) onFulfilled = typeof onFulfilled === ‘function‘ ? onFulfilled : function(value) return value; ; onRejected = typeof onRejected === ‘function‘ ? onRejected : function(err) throw new Error(err); ; var self = this, promise2; if(self.state === ‘fulfilled‘) promise2 = new Promise(function(resolve, reject) setTimeout(function() try //将x处理成一个原始值 var x = onFulfilled(self.value); resolvePromise(promise2, x, resolve, reject); catch(e) reject(e); ) ) if(self.state === ‘rejected‘) promise2 = new Promise(function(resolve, reject) setTimeout(function() try //将x处理成一个原始值 var x = onRejected(self.reason); resolvePromise(promise2, x, resolve, reject); catch(e) reject(e); ) ) if(self.state === ‘pending‘) promise2 = new Promise(function(resolve, reject) self.callbackResolveFn.push(function() setTimeout(function() try //将x处理成一个原始值 var x = onFulfilled(self.value); resolvePromise(promise2, x, resolve, reject); catch(e) reject(e); ) ); self.callbackRejectFn.push(function() setTimeout(function() try //将x处理成一个原始值 var x = onRejected(self.reason); resolvePromise(promise2, x, resolve, reject); catch(e) reject(e); ) ); ) return promise2; Promise.prototype[‘catch‘]= function (callback) return this.then(undefined, callback) Promise.all = function (promises) return new Promise(function (resolve, reject) let arr = []; let i = 0; function processData(index, y) arr[index] = y; if (++i === promises.length) resolve(arr); for (let i = 0; i < promises.length; i++) promises[i].then(function (y) processData(i, y) , reject) ) Promise.race = function (promises) return new Promise(function (resolve, reject) for (var i = 0; i < promises.length; i++) promises[i].then(resolve,reject) ); Promise.resolve = function(value) return new Promise(function(resolve,reject) resolve(value); ); Promise.reject = function(reason) return new Promise(function(resolve,reject) reject(reason); ); Promise.defer = Promise.deferred = function () var d = ; d.promise = new Promise(function (resolve, reject) d.resolve = resolve; d.reject = reject; ); return d module.exports = Promise;
promise-aplus-tests
由于是参(抄)考(袭)前辈的polyfill,自己编码测试时出现了两处错误,ES6 Promise 规范的2.3.1和2.3.4
2.3.1
2.3.4
经过改正测试成功
后记
你们的支持是我最大的动力,熬夜码字不易,如果此文对你有帮助,请不吝star--->https://github.com/chenchangyuan/promise
有兴趣加笔者好友的同学请扫描下方二维码(1.本人微信,2.微信公众号,3.技术交流微信群),愿与您成为好友共同探讨技术,畅聊生活!
参考资料
http://liubin.org/promises-book
https://juejin.im/post/5ab20c58f265da23a228fe0f
es6——异步操作之promise(代码片段)
基本概念: Promise:是ES6中新增的异步编程解决方案,提现在代码中他是一个对象可以通过Promise构造函数来实例化。 -newPromise(cb)===>实例的基本使用,PendingResolvedRejected >两个原型方法: -Promise.prototype.then()-Prom... 查看详情
es6之promise简单理解及使用(代码片段)
promise1.promise是解决异步的一种方案,也就是让promise帮我们去处理异步,最终promise会返回异步处理的结果。2.有了promise之后,让异步处理更加灵活,还能够解决之前的回调地狱的问题。promise的使用我们需要用promise帮我们处理异... 查看详情
异步编程解决方案之promise/deferred(代码片段)
Promise三种状态:未完成、完成态、失败态varevents=require(‘events‘);varutil=require(‘util‘);varEventEmitter=events.EventEmitter;varPromise=function()EventEmitter.call(this);util.inherits(Promise,EventEmitter);Promis 查看详情
ecmascript6_异步编程之promise(代码片段)
Promise对象异步编程方案,已同步的方式表达异步的代码,解决回调地狱的问题比传统的解决方案——回调函数和事件——更合理和更强大是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的... 查看详情
#打卡不停更#三方库移植之napi开发[4]异步调用:callback&promise(代码片段)
...CPU密集型任务需要异步处理。NAPI支持异步模型,提供了Promise、Callback2种方式。往期回顾:三方库移植之NAPI开发[1]—HelloOpenHarmonyNAPI三方库移植之NAPI开发[2]C/C++与JS的数据类型转换三方库移植之NAPI 查看详情
vue之前后端交互(代码片段)
...码需要嵌套JS中常见的异步调用定时任务ajax事件函数二、promise(类型是构造函数)主要解决异步深层嵌套的问题(回调地狱)promise提供了简洁的API,使得异步操作更加容易2.1Promise的基本用法<scripttype="text/javascript">/*1.Promise... 查看详情
web前端练习19----es6新语法6,异步任务promise(代码片段)
百度搜索 mdn promise https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/PromisePromise基本用法,模拟请求数据functionmyAsyncTask(time)varpromise1=newPromise(function(success,f 查看详情
手写promise(代码片段)
...而言就显得尤为重要,其中在面试中被问道最多的就是对Promise方法的掌握情况,本章将和大家一起分析和完成一个Promise方法,希望对你的学习有一定的帮助。了解Promise既然我们是要模仿ES6的Promise,那我们必然要知道这个方法... 查看详情
这次聊聊promise对象(代码片段)
...海量技术实践干货哦~本文由前端林子发表于云+社区专栏Promise是CommonJS提出的一种规范,在ES6中已经原生支持Promise对象,非ES6环境可以用Bluebird等库来支持。0.引入在js中任务的执行模型有两种:同步模式和异步模式。同步模式:... 查看详情
es6之promise用法详解(代码片段)
一前言本文主要对ES6的Promise进行一些入门级的介绍。要想学习一个知识点,肯定是从三个方面出发,what、why、how。下面就跟着我一步步学习吧~二什么是Promise首先是what。那么什么是Promise呢? 以下是MDN对Promise的定义ThePromiseo... 查看详情
javascript系列之es6篇(代码片段)
八,Promise异步1,Promise简介(1)含义:promise是ES6引出的新的异步编程的解决方案,语法上promise是一个构造函数,用来封装异步操作并且可以获取其成功或失败的结果。2,简单的promise用例constp=n... 查看详情
[前端学习]promise对象一网打尽(代码片段)
文章目录Promise.prototype.finally()Promise.all()Promise.race()Promise.allSettled()Promise.any()Promise.resolve()Promise.reject()Promise.try()Promise的含义Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大 查看详情
[前端学习]promise对象一网打尽(代码片段)
文章目录Promise.prototype.finally()Promise.all()Promise.race()Promise.allSettled()Promise.any()Promise.resolve()Promise.reject()Promise.try()Promise的含义Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大 查看详情
关于promise(代码片段)
...都完成后才能执行后续的任务,无法实现并行节约时间2.PromisePromise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的 查看详情
前端异步流程工具(代码片段)
前端异步流程工具传统:回调函数流行:Promise*最流行constp1=newPromise(function(resolve,reject)resolve(‘任务一‘)).then(function(data)console.log(data))constp2=newPromise(function(resolve,reject)setTimeout(function()resol 查看详情
promise.all的异常处理,前端开发者需了解(代码片段)
文章目录Promise.all的基本使用问题:需自己catch返回失败的值Promise.allSettled方法背景咱们在开发中,大多数时间都是一个异步操作一个异步操作去执行的,但是有一些特殊情况,需要一股脑去执行多个异步操作,比... 查看详情
关于promise详解(代码片段)
...作都完成后才能执行后续的任务,无法实现并行节约时间PromisePromise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才... 查看详情
promise学习笔记(代码片段)
注:笔记来自于视频尚硅谷Web前端Promise教程从入门到精通注:如果是初学仅需要学会Promise的基本使用即可,不要陷入要自己实现手写Promise中。Promise的理解和使用Promise是什么Promise是一门新的技术,ES6技术规范。P... 查看详情