Promise 对象

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_javascript

基本概念 

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实操

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_php_02

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对象_方法

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_前端_03

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对象的异步应用

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_前端_04

 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 函数的语法

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_php_05

 基本用法

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 函数的异步应用

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_vue.js_06

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 函数

ECMAScript6新特性【Promise 对象(Ajax实操、方法、异步应用、Generator 函数(语法、异步应用)Async 函数 】(九)-全面详解(学习总结---从入门到深化)_前端_07

 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是新的网络请求解决方案