- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
抽象表达
Promise是一门新的技术(ES6规范)
Promise是JS中进行异步编程的新解决方案
(旧方案是单纯使用回调函数)
具体表达
从语法上来说:Promise是一个构造函数
从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功或者失败的结果值
指定回调函数的方式更加灵活
旧的:必须在启动异步任务前指定
Promise:启动异步任务 => 返回Promise对象 => 给 Promise对象绑定回调函数(甚至可以在异步任务结束后指定多个)
支持链式调用,可以解决回调地狱问题
什么是回调地狱?回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件
asyncFunc1(opt,(...args1)=>{
asyncFunc2(opt,(...args2)=>{
asyncFunc3(opt,(...args3)=>{
asyncFunc4(opt,(...args4)=>{
// some operation
})
})
})
})
const xhr = new XMLHttpRequest;
xhr.open('GET','https://api.apiopen.top/getJoke');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >=200 && xhr.status < 300){
console.log(xhr.response);
}else{
console.log(xhr.status)
}
}
}
const p = new Promise((resolve,reject)=>{
//1、创建对象
const xhr = new XMLHttpRequest;
//2、初始化
xhr.open('GET','https://api.apiopen.top/getJoke');
//3、发送
xhr.send();
//4、处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//判断响应状态码
if(xhr.status >=200 && xhr.status <300){
//控制台输出响应体
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
function mineReadFile(path){
return new Promise((resolve,reject)=>{
require('fs').readFile(path,(err,data)=>{
if(err) reject();
resolve();
})
})
}
传入一个遵循常见错误优先的回调风格的函数((err,value) =>...
),并返回一个promise版本
最常见的就是fs的readfile函数
const util = require('util');
const fs = require('fs');
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./Promise/resource/context.txt').then(res => {
console.log(res.toString(),'haha');
}).catch(err => {
console.log(err)
})
异步操作之后会有三种状态:
实例对象中的另一个属性 「PromiseResult」
保存着异步任务「成功/失败」的结果
执行异步操作成功,执行resolve执行异步操作失败,执行rejectnew PromisePromise对象resolve状态Promise对象reject状态回调onResolved回调onRejected新的Promise对象
如何改变promise的状态?
resolve(value):如果当前是pending就会变为resolved
reject(reason): 如果当前是pending就会变为rejected
抛出异常throw:如果当前是pending就会变为rejected
一个promise指定多个成功/失败回调函数,都会调用吗?
当promise改变为对应状态时都会调用
promise如何串连多个操作任务
promise的then返回一个新的promise,可以看成then()链式调用
通过then的链式调用串连多个同步、异步任务
promise异常穿透?
当使用promise的then链式调用时,可以在最后指定失败的回调
前面任何操作出了异常,都会传到最后失败的回调中处理
中断promise链?
当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
办法:在回调函数中返回一个pending状态的promise对象
/*
** 手写Promise
*/
function Promise(executor){
}
//添加 then 方法
Promise.prototype.then = function(onResolved,onRejected){}
/*
** 手写Promise
*/
function Promise(executor){
//resolve 函数
function resolve(data){
}
//reject 函数
function reject(data){
}
//同步调用「执行器函数」
executor();
}
//添加 then 方法
Promise.prototype.then = function(onResolved,onRejected){}
/*
** 手写Promise
*/
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
const self = this;
//resolve 函数
function resolve(data){
//1、修改对象的状态
self.PromiseState = 'fulfilled'
//2、设置对象结果值
self.PromiseResult = data
}
//reject 函数
function reject(data){
//1、修改对象的状态
self.PromiseState = 'rejected'
//2、设置对象结果值
self.PromiseResult = data
}
//同步调用「执行器函数」
executor(resolve,reject);
}
//添加 then 方法
Promise.prototype.then = function(onResolved,onRejected){}
使用try{}catch(e)捕捉异常;
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
在resolve,reject函数内部添加if(self.PromiseState !== 'pending') return
语句即可
//添加 then 方法
Promise.prototype.then = function(onResolved,onRejected){
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
首先存储回调函数,等待状态改变后再执行
//添加 then 方法
Promise.prototype.then = function(onResolved,onRejected){
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
if(this.PromiseState === 'pending'){
//保存回调函数
this.callback = {
onResolved,
onRejected
}
}
}
function Promise(executor){
//添加属性
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callback = {};
const self = this;
//resolve 函数
function resolve(data){
//1、修改对象的状态
if(self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
//2、设置对象结果值
self.PromiseResult = data
//3、执行回调函数
if(self.callback.onResolved){
self.callback.onResolved(data);
}
}
//reject 函数
function reject(data){
if(self.PromiseState !== 'pending') return
//1、修改对象的状态
self.PromiseState = 'rejected'
//2、设置对象结果值
self.PromiseResult = data
//3、执行回调函数
if(self.callback.onRejected){
self.callback.onRejected(data);
}
}
//同步调用「执行器函数」
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
使用数组存储回调函数,通过数组遍历进行调用多个回调函数
this.callbacks = [];//修改为数组
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved,
onRejected
})
}
//resolve 函数
function resolve(data){
//1、修改对象的状态
if(self.PromiseState !== 'pending') return
self.PromiseState = 'fulfilled'
//2、设置对象结果值
self.PromiseResult = data
//3、执行回调函数
self.callbacks.forEach(item => {
item.onResolved(data)
})
}
//reject 函数
function reject(data){
if(self.PromiseState !== 'pending') return
//1、修改对象的状态
self.PromiseState = 'rejected'
//2、设置对象结果值
self.PromiseResult = data
//3、执行回调函数
self.callbacks.forEach(item => {
item.onRejected(data)
})
}
Promise返回是一个Promise对象
所以:
Promise.prototype.then = function(onResolved,onRejected){
return new Promise((resolve,reject) => {
if(this.PromiseState === 'fulfilled'){
try{
let result = onResolved(this.PromiseResult);
if(result instanceof Promise){
//如果result是一个Promise对象,那么返回的Promise对象的状态根据result的状态来定
result.then(v => {
resolve(v)
},r => {
reject(r)
})
}else{
//对象的状态为「成功」
resolve(result);
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved,
onRejected
})
}
})
}
const self = this;
...
...
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved:function(){
try{
let result = onResolved(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {resolve(v)}, r => {reject(r)});
}else{
resolve(result);
}
}catch(e){
reject(e);
}
},
onRejected:function(){
try{
let result = onRejected(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {resolve(v)}, r => {reject(r)});
}else{
resolve(result);
}
}catch(e){
reject(e);
}
}
})
}
对重复性的代码进行封装
Promise.prototype.then = function(onResolved,onRejected){
return new Promise((resolve,reject) => {
const self = this;
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {
resolve(v)
},r => {
reject(r)
})
}else{
//对象的状态为「成功」
resolve(result);
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'fulfilled'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved:function(){
callback(onResolved)
},
onRejected:function(){
callback(onRejected)
}
})
}
})
}
添加catch方法
//添加 catch方法
Promise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected);
}
异常穿透与值传递
Promise.prototype.then = function(onResolved,onRejected){
return new Promise((resolve,reject) => {
const self = this;
//异常穿透
if(typeof onRejected !== 'function'){
onRejected = reason => {
throw reason
}
}
//值传递
if(typeof onResolved !== 'function'){
onResolved = value => value
}
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v => {
resolve(v)
},r => {
reject(r)
})
}else{
//对象的状态为「成功」
resolve(result);
}
}catch(e){
reject(e);
}
}
if(this.PromiseState === 'fulfilled'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
if(this.PromiseState === 'pending'){
//保存回调函数
this.callbacks.push({
onResolved:function(){
callback(onResolved)
},
onRejected:function(){
callback(onRejected)
}
})
}
})
}
//添加 Promise.resolve方法
Promise.resolve = function(value){
return new Promise((resolve, reject) => {
if(value instanceof Promise){
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
}else{
resolve(value)
}
})
}
//添加 Promise.reject方法
Promise.reject = function(reason){
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加 Promise.all 方法
Promise.all = function(promises){
return new Promise((resolve, reject) => {
let count = 0;
let arr = [];
promises.forEach((item, index) => {
item.then(v => {
//每个对象都成功,返回的才会是成功的
count++;
arr[index] = v;
if(count === promises.length){
resolve(arr);
}
}, r => {
reject(r)
})
})
})
}
//添加 Promise.race方法
Promise.race = function(promises){
return new Promise((resolve, reject) => {
promises.forEach((item) => {
item.then(v => {
resolve(v);
}, r => {
reject(r)
})
})
})
}
//Promise.prototype.then
if(this.PromiseState === 'fulfilled'){
setTimeout(() => {
callback(onResolved);
})
}
if(this.PromiseState === 'rejected'){
setTimeout(() => {
callback(onRejected);
})
}
//function Promise()
...
//异步执行回调函数
setTimeout(()=>{
self.callbacks.forEach(item => {
item.onResolved(data)
})
})
async function func(){
return 'promise'
}
console.log(func());
//Promise { 'promise' }
注意:
读取文件内容
const fs = require('fs');
const util = require('util')
const mineReadFile = util.promisify(fs.readFile)
async function main(){
let data = await mineReadFile('./Promise/resource/context.txt');
console.log(data.toString())
}
main();
结合发送AJAX请求
function sendAJAX(url){
const p = new Promise((resolve,reject)=>{
//1、创建对象
const xhr = new XMLHttpRequest;
//2、初始化
xhr.open('GET',url);
//3、发送
xhr.send();
//4、处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//判断响应状态码
if(xhr.status >=200 && xhr.status <300){
//控制台输出响应体
resolve(xhr.response);
}else{
reject(xhr.status);
}
}
}
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
}
async function awaitAJAX(){
let data = await sendAJAX('https://api.apiopen.top/getJoke');
}
如何从 promise 中退出 promise ? perl6 文档没有提供简单的方法。例如: my $x = start { loop { # loop forever until "qui
我的用户 Controller 中有一个索引操作,其中我试图连续做两件事,并且在它们都有机会完成之前不执行所需的 res.json() 方法。 我有一个加入用户的友谊加入模型。一列是 friender
请帮我解释一下为什么日志结果有两种不同: 方式 1:每 1 秒顺序记录一次 方式 2:1 秒后记录所有元素。 // Way 1 let sequence = Promise.resolve(); [1
我的问题很简单。 Promise.all() 方法可以返回 Promise 吗?让我解释一下: function simpleFunction() { let queue = [];
我正在使用 Promise 从存储中读取文件并转换为 base64 字符串。我有图像数组,使用 RNFS 读取图像 const promise_Images = _Images.map(async (
如果使用非空数组调用 Promise.all 或 Promise.race,它们将返回一个待处理的 Promise: console.log(Promise.all([1])); // prints
Promise.all 是否可以在没有包装 promise 的情况下返回链的最后一个值? 如果不使用 await,它在我的上下文中不起作用 没有包装的例子: function sum1(x){ r
我一直在玩 promise,通常能想出如何处理好它们,但在这种情况下,我不知道如何删除一个 promise-wrapping level。 代码如下: let promise2 = promise1.
考虑以下嵌套的Promises结构: const getData = async() => { const refs = [{ name: "John33", age: 3
我已经阅读了 Promise/A+ 规范,但据我了解,还有诸如 Promise/A 和 Promise 之类的东西。它们之间有什么区别? Promise 和 Promise/A 规范也是如此吗?如果是
当我运行以下代码时: my $timer = Promise.in(2); my $after = $timer.then({ say "2 seconds are over!"; 'result'
以下简单的 promise 是发誓的,我不允许打破它。 my $my_promise = start { loop {} # or sleep x; 'promise re
我正在尝试扩展Promise: class PersistedPromise extends Promise { } 然后在派生类上调用静态resolve以直接创建一个已解决的Promise: Per
我有两个返回 promise 的函数,我独立使用它们作为: getLocal().then(...) 和 getWeb().then(...) 但是现在我遇到了一个奇怪的问题: 1) 我需要第三个
我不知道 promise.all 解决方案中的 promise.all 是否是一个好的实践。我不确定。 我需要从一组用户获取信息,然后通过此信息响应,我需要发送消息通知。 let userList =
我一直在尝试使用 queueMicrotask() 函数,但我没有弄清楚当回调是微任务时回调的优先级如何。查看以下代码: function tasksAndMicroTasks() { const
我一直在尝试使用 queueMicrotask() 函数,但我没有弄清楚当回调是微任务时回调的优先级如何。查看以下代码: function tasksAndMicroTasks() { const
今年早些时候,我在 Pharo Smalltalk 参与了一个 promise 项目。这个想法是为了实现以下行为: ([ 30 seconds wait. 4 ]promiseValue )then:
大家好,提前感谢您的帮助。 下面是我正在尝试做的事情 function1(){ throw some error(); } function2() { // dosomething suc
我有以下未解析的代码。f2 解决了,所以我不会添加该代码,它是 f1 我有问题。 我调用函数,它到达最里面如果,它调用函数“find”,它执行函数 findId,完美返回 Id,然后执行 editId
我是一名优秀的程序员,十分优秀!