Promise 对象
基本概念
Promise 是异步编程的一种解决方案,比传统的解决方案——回调 函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise
所谓 Promise
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来, 避免了层层嵌套的回调函数。此外, Promise
基本用法
ES6 规定, Promise 对象是一个构造函数,用来生成 Promise 实例
const promise = new Promise(function(resolve,reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject 。它们是两个函数,由 JavaScript 引擎提供,不用自己 部署
Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected
promise.then(function(value) {
// success
}, function(error) {
// failure
});
加载图片资源例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div></div>
<script>
function loadImageAsync(url) {
var promise = new Promise(function (resolve, reject) {
const image = new Image();
image.onload = function () {
resolve(image);
};
image.onerror = function () {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
return promise;
}
loadImageAsync("http://iwenwiki.com/api/vue-data/vue-data-1.png")
.then(function(data){
console.log(data);
$("div").append(data)
},function(error){
$("div").html(error)
})
</script>
</body>
</html>
实时效果反馈
1. Promise
A Promise
B Promise
C Promise
D Promise
Promise对象_Ajax实操
Promise封装Ajax,让网络请求的异步操作变得更简单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const getJSON = function (url) {
const promise = new Promise(function (resolve, reject) {
const handler = function () {
if (this.readyState !== 4) {
return; }
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("http://iwenwiki.com/api/blueberrypai/getIndexBanner.php").then(function(json)
{
console.log(json);
}, function (error) {
console.error('出错了', error);
});
</script>
</body>
</html>
Promise对象_方法
then()
Promise 实例具有 then 方法,也就是说, then 方法是定义在原型对象 Promise.prototype
then 方法返回的是一个新的 Promise 实例。因此可以采用链式写法, 即 then 方法后面再调用另一个 then
getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
},function (err){
console.log("rejected: ", err);
});
catch()
catch() 方法是 .then(null, rejection) 或 .then(undefined, rejection) 的别名,用于指定发生错误时的回调函数
getJSON("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php").then(
data =>{
console.log(data)
throw new Error('test');
},
error =>{
console.log("error"+error);
}
).catch(err =>{
console.log("catch"+err);
})
finally()
finally()
getJSON("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php").then(
data =>{
console.log(data)
},
error =>{
console.log("error"+error);
}
).catch(err =>{
console.log("catch"+err);
}).finally(() =>{
console.log("成功失败都会执行");
})
all()
Promise.all()
优点就是多个promise都有结果,才会触发 then 或者 catch
var url1 = "http://iwenwiki.com/api/musicimg/1.png"
var url2 = "http://iwenwiki.com/api/musicimg/2.png"
var promise1 = new Promise(function (resolve, reject) {
var image = new Image();
image.src = url1;
image.onload = function () {
resolve(image)
}
image.onerror = function () {
reject(new Error('Could not load image at ' + url1))
}
})
var promise2 = new Promise(function (resolve, reject) {
var image = new Image();
image.src = url2;
image.onload = function () {
resolve(image)
}
image.onerror = function () {
reject(new Error('Could not load image at ' + url2))
}
})
Promise.all([promise1,promise2]).then(data =>{
console.log(data);
}).catch(error =>{
console.log(error);
})
实时效果反馈
1. 下列那个方法可以不管成功失败都会触发:
A then
B catch
C finally
D all
Promise对象的异步应用
Promise
原始写法
$.getJSON("http://localhost/generator/list.php",function(data){
$.getJSON("http://iwenwiki.com/api/generator/id.php",{id:data[0]},function(data){
$.getJSON("http://iwenwiki.com/api/generator/name.php",{name:data.name},function(data){
console.log(data);
})
})
})
Promise全新写法
function getIds(){
return new Promise(function(resolve,reject){
$.getJSON("http://localhost/generator/list.php",function(data){
resolve(data)
},function(error){
reject(error)
})
})
}
getIds().then(data =>{
return new Promise((resolve,reject) =>{
$.getJSON("http://iwenwiki.com/api/generator/id.php", { id: data[0] },function(data){
resolve(data)
},function(error){
reject(error)
})
})
}).then(data =>{
return new Promise((resolve,reject) =>{
$.getJSON("http://iwenwiki.com/api/generator/name.php", { name: data.name },function(data){
resolve(data)
},function(error){
reject(error)
})
})
}).then(data =>{
console.log(data);
})
Generator 函数的语法
基本用法
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与 传统函数完全不同 Generator 函数有多种理解角度。语法上,首先可以把它理解成, Generator 函数是一个状态机,封装了多个内部状态。
形式上,Generator 函数是一个普通函数,但是有两个特征。一 是, function 关键字与函数名之间有一个星号;二是,函数体内部使 用 yield 表达式,定义不同的内部状态( yield
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
console.log(hw.next());
// { value: 'hello', done: false }
console.log(hw.next());
// { value: 'world', done: false }
console.log(hw.next());
// { value: 'ending', done: true }
console.log(hw.next());
// { value: undefined, done: true }
ES6 没有规定, function
function * foo(x, y) { ··· }
function *foo(x, y) { ··· }
function* foo(x, y) { ··· }
function*foo(x, y) { ··· }
for...of 循环
for...of 循环可以自动遍历 Generator 函数,且此时不再需要调用 next 方法。
function* foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
for (let v of foo()) {
console.log(v);
}
// 1 2 3 4 5
实时效果反馈
1. Generator
A Generator的作用是完成网络请求,如Ajax一样
B Generator的作用是完成异步网络请求,如Ajax一样
C Generator是新的网络请求解决方案
D Generator是新的异步网络请求解决方案
Generator 函数的异步应用
Generator 对异步处理的回调地狱的改善也是非常明显的
$.getJSON("http://localhost/generator/list.php",function(data){
$.getJSON("http://iwenwiki.com/api/generator/id.php",{id:data[0]},function(data){
$.getJSON("http://iwenwiki.com/api/generator/name.php",{name:data.name},function(data){
console.log(data);
})
})
})
function ajax(url){
$.getJSON(url,function(data){
info.next(data)
})
}
function* getInfo(){
const ids = yield
ajax("http://localhost/generator/list.php");
const name = yield
ajax("http://iwenwiki.com/api/generator/id.php?id="+ids[0]);
const infos = yield
ajax("http://iwenwiki.com/api/generator/name.php?name="+name.name)
console.log(infos);
}
var info = getInfo();
info.next();
Async 函数
ES2017 标准引入了 async 函数,使得异步操作变得更加方便 async 函数是什么?一句话,它就是 Generator 函数的语法糖
基本语法
function print(){
setTimeout(() =>{
console.log("定时器");
},1000)
console.log("Hello");
}
print()
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
异步应用
function ajax(url){
return new Promise(function(resolve,reject){
$.getJSON(url,function(result){
resolve(result)
},function(error){
reject(error)
})
})
}
async function getInfo(){
let ids = await
ajax("http://iwenwiki.com/api/generator/list.php")
let names = await
ajax("http://iwenwiki.com/api/generator/id.php?id="+ids[0])
let infos = await
ajax("http://iwenwiki.com/api/generator/name.php?name=" + names.name)
console.log(infos);
}
getInfo();
实时效果反馈
1. Async
A Async是完成网络请求,如Ajax一样
B Async的作用是完成异步网络请求,如Ajax一样
C Async是Generator新的语法糖
D Async是新的网络请求解决方案