热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[JavaScript]promise概述

promisepromise是es6提出的一个异步解决方案,比传统回调事件的写法更加合理更加强大,主要还是优雅promise有pending(等待中),fulfilled(已成功)

promise

promise 是 es6 提出的一个异步解决方案,比传统回调事件的写法更加合理更加强大,主要还是优雅

promise 有 pending(等待中),fulfilled(已成功),rejected(已失败),只有异步操作的结果才能够将状态改变,且只会有 pending->fulfilled 或者 pending->rejected,只要状态改变,会一直保持这个结果

const p = new Promise((resolve, reject) => {
if (true) {
resolve("成功"); //将状态由pending->fulfilled
} else {
reject("失败"); //将状态由pending->rejected
}
});
console.log(p);


方法



  • then(fulfilled_callback,[,rejected_callback])

then 方法中包含两个参数,第一个参数(必须,但是不限定是函数)是 fulfilled 的回调函数,第二个参数(可选)是 rejected 的回调函数

then 方法返回的是一个全新的 promises 实例,与之前状态改变的不一样,之前的 promise 状态改变,就会一直保持改变的结果.同时由于是返回一个全新的 primise,类似于 jquery 的 return this,所以可以一直调用 promise 的方法, p.then().then().all()......

"use strict";
const createPromise = function(bool) {
return new Promise((resolve, reject) => {
if (bool) {
resolve("我们成功了"); //状态由pending->fulfilled,我们成功了
} else {
reject("还是失败了");
}
});
};
createPromise(true).then(
function(value) {
console.log(value);
},
function(error) {
console.log(error);
}
);
createPromise(false).then(
function(value) {
console.log(value);
},
function(error) {
console.log(error); ////状态由pending->rejected,还是失败了
}
);

同时 then 的第一个方法可以传其他值,比如数字数组,对象...都可以执行,作用就是 catch()方法,但是第二个参数传其他类型值就报错


createPromise(false).then(null, function(error) {
console.log(error); //还是失败了
});
createPromise(false).then(undefined, function(error) {
console.log(error); //还是失败了
});
createPromise(false).then([1, 2, 3], function(error) {
console.log(error); //还是失败了
});
createPromise(false).then({ a: "1" }, function(error) {
console.log(error); //还是失败了
});
createPromise(false).then("刘德华", function(error) {
console.log(error); //还是失败了
});


  • catch

Promise.prototype.catch 方法是.then(null, rejection)或.then(undefined, rejection)

"use strict";
const createPromise = function(bool) {
return new Promise((resolve, reject) => {
if (bool) {
resolve("我们成功了");
} else {
reject("还是失败了");
}
});
};
createPromise(false)
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error); //还是失败了,更then的第二个方法一样
});

catch 不止是 rejected 回调,当运行到 then 的 fulfilled 回调事件中出错依然能够捕获

但是 then(xxx,rejected_callback)无法这样捕获

createPromise(true)
.then(result => {
console.log(result); //我们成功了
throw new Error('我在then里面出错了,怎么办');
})
.catch(error => {
console.log(error); //Error: 我在then里面出错了,怎么办
});
createPromise(true).then(
result => {
console.log(result); //我们成功了
throw new Error("我在then里面出错了,怎么办");
},
error => {
console.log(error); //Uncaught (in promise) Error: 我在then里面出错了,怎么办
}
);

当 promise 已经由 pending->fulfilled 或者 pending->rejected 之后,再报错也不会进行状态改变,可以认为当前 promise 实例已经在这一刻化为了永恒,亘古不变

new Promise((resolve, reject) => {
// resolve("我将走在错误的前面");
reject("我将走在错误的前面的错误")
throw new Error("我在fulfilled后面了");
}).then(
result => {
console.log(result); //我将走在错误的前面
},
error => {
console.log(error); //我将走在错误的前面的错误
}
);

catch 捕获错误是层层向下传递的,错误总会被下面接触的第一个 catch 捕获到

new Promise((resolve, reject) => {
resolve("我将走在错误的前面");
})
.then(result => {
console.log(result); //我将走在错误的前面
throw new Error('菜就不走了')
return "走后面的菜";
})
.then(result => {
console.log(result);
return "比我还菜";
})
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error); //Error: 菜就不走了
});


  • finally

    finally 不管状态是 fulfilled 还是 rejected 都会执行,与状态无关



new Promise((resolve, reject) => {
resolve("今天是个好日子");
})
.then(result => {
console.log(result); //今天是个好日子
throw new Error("出错了");
})
.catch(error => {
console.log(error); //Error: 出错了
})
.finally(() => {
console.log("finally"); //finally
});


  • all(array)



  1. all 的参数是数组,数组里面可以包含多个 promise 实例

  2. 只有数组里面的所有 promise 状态都变为 fulfilled,Promise.all 状态才会变为 fulfilled,数组中有一个是 rejected,状态就是 rejected

  3. 如果是网络请求或者文件读取等耗时任务,会按照短板原则执行,也就是只有当最后一个耗时最长的任务完成,才会执行下一步

//在./file文件新建01,02,03三个txt
const fs = require("fs");
const path = require("path");
Promise.all([create_promise(path.resolve(__dirname, "./file/01.txt")), create_promise(path.resolve(__dirname, "./file/02.txt")), create_promise(path.resolve(__dirname, "./file/03.txt"))]).then(result => {
console.log(result);
});
function create_promise(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, "utf-8", (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}



  • race

race 总体写法更 all 方法类似,只是 race 的执行是长板原则,按照最长的那个板子来进行状态切换,多个请求只要有一个由 pending->fulfilled,那么整体的状态也改变了

const fs = require("fs");
const path = require("path");
Promise.race([create_promise(path.resolve(__dirname, "./file/01.txt")), create_promise(path.resolve(__dirname, "./file/02.txt")), create_promise(path.resolve(__dirname, "./file/03.txt"))]).then(result => {
console.log(result);
});
function create_promise(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, "utf-8", (error, data) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
});
}



  • resolve

resolve 是将现有对象转化为 promise 对象



  1. 参数是一个 promise 实例,resolve 将不做任何修改,直接返回

console.log(
new Promise((resolve, reject) => {
resolve("今日是个好日子");
})
); //Promise {: "今日是个好日子"}
console.log(
Promise.resolve(
new Promise((resolve, reject) => {
resolve("今日是个好日子");
})
)
); //Promise {: "今日是个好日子"}


  1. 参数是一个 thenable 对象,会将这个对象转为 Promise 对象,然后就立即执行 thenable 对象的 then 方法

var thenable = {
then: function(resolve, reject) {
resolve("今天是个好日子");
}
};
var p = Promise.resolve(thenable);
p.then(value => console.log(value)); //今天是个好日子


  1. 参数不是带有 then 的对象,会返回一个新的 promise 对象,其状态直接是 resolved 状态

var p = Promise.resolve([1, 2, 3, 4, 5]);
p.then(value => console.log(value)); //[1,2,3,4,5]


  1. 无参数,返回一个状态是 resolved 状态的 promise 对象

var p = Promise.resolve();
p.then(value => console.log(value)); //undefiend


  • reject

reject()会返回一个新的 promise 实例,状态是 rejected

var p1 = Promise.reject("我错了");
var p2 = new Promise((resolve, reject) => {
reject("绝对错了");
});
p1.catch(error => console.log(error)); //我错了
p2.catch(error => console.log(error)); //绝对错了

reject()方法的参数不会抓取抛出的错误,而是直接将参数整体传递给后面的方法当作参数

var thenable = {
then: function(resolve, reject) {
reject("出错了");
}
};
Promise.reject(thenable).catch(error => {
console.log(error); //{then: ƒ}
});

翻译 Promises/A+规范

深入 Promise(一)——Promise 实现详解

Promise 对象

透彻掌握 Promise 的使用,读这篇就够了

大白话讲解 Promise(一)

JS 中的 Promise 的 then 方法做了啥?



推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
author-avatar
萧海豚泳_756
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有