Promise 用法
Posted wgchen~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Promise 用法相关的知识,希望对你有一定的参考价值。
阅读目录
promise是什么?
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
为什么会有promise?
为了避免界面冻结(任务)
同步:
假设你去了一家饭店,找个位置,叫来服务员,这个时候服务员对你说,对不起我是“同步”服务员,我要服务完这张桌子才能招呼你。
那桌客人明明已经吃上了,你只是想要个菜单,这么小的动作,服务员却要你等到别人的一个大动作完成之后,才能再来招呼你,这个便是同步的问题:也就是“顺序交付的工作1234,必须按照1234的顺序完成”。
异步:
则是将耗时很长的A交付的工作交给系统之后,就去继续做B交付的工作。
等到系统完成了前面的工作之后,再通过回调或者事件,继续做A剩下的工作。
AB工作的完成顺序,和交付他们的时间顺序无关,所以叫“异步”。
有了nodeJS之后…
对异步的依赖进一步加剧了
大家都知道在nodeJS出来之前php、Java、python等后台语言已经很成熟了,nodejs要想能够有自己的一片天,那就得拿出点自己的绝活:
无阻塞高并发,是nodeJS的招牌,要达到无阻塞高并发异步是其基本保障
举例:
查询数据从数据库,PHP第一个任务查询数据,后面有了新任务,那么后面任务会被挂起排队;
而nodeJS是第一个任务挂起交给数据库去跑,然后去接待第二个任务交给对应的系统组件去处理挂起,接着去接待第三个任务…那这样子的处理必然要依赖于异步操作。
promise 是一个对象
promise 是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据
代码风格,容易理解,便于维护
多个异步等待合并便于解决
promise详解
new Promise(
function (resolve, reject) {
// 一段耗时的异步操作
resolve('成功') // 数据处理完成
// reject('失败') // 数据处理出错
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失败
)
resolve 作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
promise有三个状态:
1、pending [待定] 初始状态
2、fulfilled [实现] 操作成功
3、rejected [被否决] 操作失败
当promise状态发生改变,就会触发 then()
里的响应函数处理后续步骤;
promise状态一经改变,不会再变。
Promise对象的状态改变,只有两种可能:
从 pending
变为 fulfilled
从 pending
变为 rejected
。
这两种情况只要发生,状态就凝固了,不会再变了。
Promise 解决回调地狱
Promise 用法
Promise 概述
Promise 是异步编程的一种解决方案,从语法上讲,Promise 是一个对象,从它可以获取异步操作的消息。
ES6 Promise
ES2015正式发布(也就是ES6,ES6是它的乳名),其中Promise被列为正式规范。作为ES6中最重要的特性之一,我们有必要掌握并理解透彻。本文将由浅到深,讲解Promise的基本概念与使用方法。
console.dir(Promise)
使用 Promise 主要有以下好处:
可以避免多层异步调用嵌套问题(回调地狱)
Promise 对象提供了简洁API,使得控制异步操作更加容易
Promise 基本用法
实例化 Promise 对象,构造函数中传递函数,该函数中用于处理异步任务
resolve
和 reject
两个参数用于处理成功和失败两种情况,并通过 p.then
获取处理结果
var p = new Promise(function(resolve,reject){
// 成功时调用 resolve()
// 失败时调用 reject()
});
p.then(function(ret){
// 从 resolve 得到正常结果
},function(ret){
// 从 reject 得到错误信息
});
示例
<script>
var p=new Promise(function(resolve,reject){
//这里用户实现异步任务
setTimeout(function(){
var flag=false;
if(flag){
//正常情况
resolve('hello');
}else{
//异常情况
reject('出错了');
}
},1000);
});
//hello传递给了data
p.then(function(data){
//打印正常信息
console.log(data);
},function(info){
//打印异常信息
console.log(info);
});
</script>
一秒后打印:
Promise基于原生ajax发送请求,php并设置跨域
<script>
//Promise基于原生ajax发送请求
function queryData(url){
var p=new Promise(function(resolve,reject){
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState!=4) return;
if(xhr.readyState==4 && xhr.status==200){
//处理正常的情况
resolve(xhr.responseText);
}else{
//处理异常的情况
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
queryData("http://dcatadmin.cc/user").then(function(data){
var obj = JSON.parse(data); //SON字符串转换成对象
console.log(obj);
alert(obj.name);
},function(info){
console.log(info);
});
</script>
php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
//主要为跨域CORS配置的两大基本信息,Origin和headers
$arr=[
'name'=>'willem',
'age'=>'30',
'sex'=>'男'
];
echo json_encode($arr);
laravel
public function getIndex()
{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
//主要为跨域CORS配置的两大基本信息,Origin和headers
$arr=[
'name'=>'willem',
'age'=>'30',
'sex'=>'男'
];
return response()->json($arr);
}
预览
基于 Promise 处理Ajax请求
queryData()
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
});
发送多次 ajax 请求
then 参数中的函数返回值
1、返回 Promise 实例对象
返回的该实例对象会调用下一个then
2、返回普通值
返回的普通值会直接传递给下一个 then,通过 then 参数中函数的参数接收该值
<script>
//Promise基于原生ajax发送请求
function queryData(url)
{
var p=new Promise(function(resolve,reject)
{
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if(xhr.readyState!=4) return;
if(xhr.readyState==4 && xhr.status==200)
{
//处理正常的情况
resolve(xhr.responseText);
}else{
//处理异常的情况
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
queryData("http://dcatadmin.cc/user").then(function(data){
var obj = JSON.parse(data); //SON字符串转换成对象
console.log(obj);
return queryData("http://dcatadmin.cc/user");
},function(info){
console.log(info);
}).then(function(data){
var obj = JSON.parse(data); //SON字符串转换成对象
console.log(obj);
return 123;
}).then(function(data){
console.log(data);
});
</script>
Promise 常用 API
1、实例方法
p.then()
得到异步任务的正确结果
p.catch
获取异常信息
p.finally()
成功与否都会执行(尚且不是正式标准)
queryData()
.then(function(data){
console.log(data);
})
.catch (function(data){
console.log(data);
})
.finally(function(data){
console.log(data);
});
<script>
function foo()
{
return new Promise(function(resolve,reject){
setTimeout(function(){
//resolve(123);
reject('error');
},1000);
});
}
foo().then(function(data){
console.log(data);
})
.catch(function(data){
console.log(data+' cuo wu catch');
})
.finally(function(){
console.log('finished');
});
</script>
3、 对象方法
Promise.all()
并发处理多个异步任务,所有任务都执行完成才能得到结果
Promise.race()
并发处理多个异步任务,只要有一个任务完成就能得到结果
Promise.all([p1,p2,p3]).then((result)=>{
console.log(result)
})
Promise.race([p1,p2,p3]).then((result)=>{
console.log(result)
})
<script type="text/javascript">
/*Promise常用API-对象方法*/
function queryData(url)
{
var p=new Promise(function(resolve,reject)
{
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if(xhr.readyState!=4) return;
if(xhr.readyState==4 && xhr.status==200){
//处理正常的情况
resolve(xhr.responseText);
}else{
//处理异常的情况
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
var p1=queryData("http://dcatadmin.cc/user");
var p2=queryData("http://dcatadmin.cc/res");
Promise.all([p1,p2]).then(function(result){
console.log(result);
});
/*
Promise.race([p1,p2]).then(function(result){
console.log(result);
});
*/
</script>
<?php
namespace App\\Http\\Controllers;
use App\\User;
use Illuminate\\Http\\Request;
use Illuminate\\Support\\Facades\\App;
class TestController extends Controller
{
public function __construct()
{
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
}
public function getIndex()
{
//主要为跨域CORS配置的两大基本信息,Origin和headers
$arr=[
'name'=>'willem',
'age'=>'30',
'sex'=>'男'
];
return response()->json($arr);
}
public function res()
{
$users = User::all()->toArray();
return response()->json($users);
}
}
fetch 概述
1、基本特性
更加简单的数据获取方式,功能更强大、更灵活,可以看做是 xhr 的升级版
基于Promise
2、语法结构
fetch(url).then(fn2)
.then(fn3)
...
.catch(fn)
<script type="text/javascript">
/*fetch API基本用法*/
fetch('http://dcatadmin.cc/res').then(function(data){
return data.text();//text返回的是Promise对象
}).then(function(data){
console.log(data);//这是打印的真实数据
});
</script>
3、fetch 请求参数
1、常用配置选项
method(String)
:HTTP 请求方法,默认为GET(GET、POST、PUT、DELETE)
body(String)
:HTTP的请求参数
headers(Object)
:HTTP的请求头,默认为 {}
响应数据格式
text()
:将返回体处理成字符串类型
json()
:返回结果和JSON.parse(reponseText)一样
fetch('/abc',{
method:'get'
}).then(data=>{
return data.text();
}).then(ret=>{
// 注意这里得到的才是最终的数据
console.log(ret);
});
2、GET请求方式的参数传递
fetch('/abc?id=1').then(data=>{
return data.text();
}).then(ret=>{
// 注意这里得到的才是最终的数据
console.log(ret);
});
fetch('/abc/2').then(data=>{
method:'get'
}).then(ret=>{
return data.text();
}).then(ret=>{
// 注意这里得到的才是最终的数据
console.log(ret);
});
Fetch 的 get 传参
<script type="text/javascript">
/*fetch API基本用法*/
/*这种形式$_GET['id']获取即可
fetch('http://localhost/fetch.php?id=33',{'method':'get'})
.then(function(data){
return data.text();//text返回的是Promise对象
}).then(function(data){
console.log(data);//这是打印的真实数据
});
*/
/*这种形式需要通过取余等与0方式*/
fetch('http://dcatadmin.cc/res?id=3&name=willem&sex=nan&age=31',{'method':'get'})
.then(function(data){
return data.text(); //text返回的是Promise对象
}).then(function(data){
console.log(data); //这是打印的真实数据
});
<<以上是关于Promise 用法的主要内容,如果未能解决你的问题,请参考以下文章