资讯专栏INFORMATION COLUMN

js 异步回调之Promise

solocoder / 1137人阅读

摘要:一旦非同步操作完成,就调用指定的回调函数,并总是返回一个对象,方便链式调用。方法接受两个回调函数作为参数,第一个参数是成功时的回调,第二个是失败时的回调。方法,方法是定义在原型对象上的,作用是为对象添加回调函数。

先上一个大家比较熟悉的例子;
以前我们写jquery ajax请求的时候,都是这样写:

$.ajax({
    url: "test.json",
    success: function(){
      alert("hello world!");
    },
    error:function(){
      alert("error");
    }
  });

后来呢在jquery1.7版本后,我们开始这样写:

$.ajax("test.json")
  .done(function(){ alert("hello world!"); })
  .fail(function(){ alert("error"); });

很明显,更改后的代码更易懂易读了。
这个是jquery的deferred对象,jquery deferred对象就是jQuery对Promises的实现,还其他有很多实现了promises的库供开发者可用。 像微软的 WinJS.Promise, when.js, q, 和dojo.Deferred,它们暴露的都是deferred对象。Promise也已经纳入了ES6,对于jQuery实现Promises我们暂时就不讲了,今天的目的是Promise。

那Promise到底是怎么回事呢?

其实呢,Promise就是一个对象,它是用来实现异步操作的,它可以让异步代码书写起来更优雅,更便于阅读。

Promise的特性:
1、Promise对象有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败),只有异步操作结果可以改变当前状态,其他操作不能改变状态,Promise对象的状态只能从“进行中”改为“已完成”或者从“进行中”改为“失败”。

2、Promise对象的then方法,就是用来指定回调函数。一旦非同步操作完成,就调用指定的回调函数,并总是返回一个promise对象,方便链式调用。而且同一个promise的then可以调用多次。

3、then方法接受两个回调函数作为参数,第一个参数是成功Resolved时的回调,第二个是失败Reject时的回调。第二个参数是可以选的,同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。
我们现在用promise来组织一下代码。

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        console.log("test123");
        setTimeout(function () {
            resolve("test");
        }, time);
    })
};
(function(){
    console.log("start");
    sleep(3000)
    .then(function(data){
        console.log(data);
        return sleep(5000);})
    .then(function(data){
        console.log(data);
        console.log("end");
    })
})();

上面代码中,sleep方法返回一个Promise实例,表示一段时间以后才会发生的结果。首先输出‘start’,然后,sleep执行后,3秒后返回“test”,触发then方法绑定的回调函数,输出回调返回值“test”,又return sleep(5000),这样第一个then的返回值,就是第二个的参数,再次执行sleep,5秒后返回‘test’,输出‘test’、"end";

好像没有什么大不了的,promises的真正强大之处在于多重的链接,在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了:它有个缺点就是链过长以后,满屏幕的then,傻傻分不清业务到底干啥了,

Promise的 api

1、Promise.resolve()
2、Promise.reject()
3、Promise.prototype.then()
4、Promise.prototype.catch()
5、Promise.all() // 所有的都有完成,相当于 且
6、Promise.race() // 完成一个即可,相当于 或

1、Promise.resolve()的作用将现有对象转为Promise对象resolvedl;
Promise.resolve("test")==new Promise(resolve=>resolve("test"))
2、Promise.reject()也是返回一个Promise对象,状态为rejected;

let p=Promise.reject("error") == let p=new Promise((resolve,reject)=>reject("error"));

 p.catch(data=>{
    console.log(data);
 })

生成一个Promise对象的实例对象p,抛出错误,状态就会变为Rejected,调用p.catch()指定的回调函数。
3、.then()方法,then方法是定义在原型对象Promise.prototype上的,作用是为Promise 对象添加回调函数。

let p=new Promise(resolve=>resolve("hello"));
p.then((resolve,reject)=>{
    console.log(resolve);
}).then(function(){
  console.log("zhangsan");
})

then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。 可以使用链式操作,指定多个then(),依次执行,上面的代码输出结果:’hello‘,"zhangsan"
4、.catch():发生错误的回调函数,同样,catch方法也是定义在原型对象Promise.prototype上的,事例同Promise.reject()的例子。注:如果Promise的状态已经变为resolved,再抛出错误是无效的。

var p = new Promise(function(resolve, reject) {
  resolve("success");
  reject("fail");
});
p.then(function(value) { console.log(value) })
  .catch(function(error) { console.log(error) }); 

输出结果:success;
5、Promise.all()的作用是同时执行多个实例,同步并行,且所以的实例都返回resolve状态,Promise才会改变为resolve状态,其中一个为rejected,promise的状态就是rejected;
注:Promise.all 方法的参数可以不是数组,但是必须是一个Iterator接口对象,且返回promise实例,否则报错:error:TypeError: [object Promise] is not iterable!

let p1 =new Promise(function(resolve,reject){
        resolve(1);
});
let p2 = new Promise(function(resolve,reject){
            resolve(2);
    });
let p3 = new Promise(function(resolve,reject){
       // reject();
        resolve(3);
    });
Promise.all([p1, p2, p3]).then(function (results) {
    console.log("success:"+results);
}).catch(function(r){
    console.log("error");
    console.log(r);
});

上面代码输出:success:1,2,3;
把 p3方法改为返回 reject();输出结果是:error;
6、Promise.race()的作用也是同时执行多个实例,只要有一个实例改变状态,Promise就改为那个实例所改变的状态;

 let p1 =new Promise(function(resolve,reject){
     setTimeout(function(){
        reject(1);
     },3000)
});
let p2 = new Promise(function(resolve,reject){
    setTimeout(function(){
        resolve(2);
    },1000)
});
Promise.race([p1, p2]).then(function (results) {
    console.log("success:"+results);
}).catch(function(results){
    console.log("error:"+results);
});
输出:success: 2;

上面代码p2首先执行完毕,改变状态为resolve,所以promise的状态被改为resolve;
我们把p1的时间改为1000,p2改为3000,也就是说p1先执行完毕,promise的状态也被改变为reject,输出:error:1

如果想深入学习,可以看一下阮一峰的《ES 6标准入门》的Promise部分http://es6.ruanyifeng.com/#do...,很详细的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81790.html

相关文章

  • JS异步编程Promise

    摘要:三是控制反转控制权在其他人的代码上,假如异步函数是别人提供的库,我们把回调函数传进去,我们并不能知道异步函数在调用回调函数之外做了什么事情。错误捕捉相比回调函数的错误无法在外部捕捉的问题,能够为一连串的异步调用提供错误处理。 前言 《JS异步编程之 callback》一文我们了解了JS 是基于单线程事件循环的概念构建的,回调函数不会立即执行,由事件轮询去检测事件是否执行完毕,当执行完有...

    Hegel_Gu 评论0 收藏0
  • javascript异步promise

    摘要:到这里,我已经发出了一个请求买汉堡,启动了一次交易。但是做汉堡需要时间,我不能马上得到这个汉堡,收银员给我一个收据来代替汉堡。到这里,收据就是一个承诺保证我最后能得到汉堡。 同期异步系列文章推荐谈一谈javascript异步javascript异步中的回调javascript异步之Promise.all()、Promise.race()、Promise.finally()javascr...

    rollback 评论0 收藏0
  • [面试专题]JS异步Promise,Generator,Async

    摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...

    孙淑建 评论0 收藏0
  • [面试专题]JS异步Promise,Generator,Async

    摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...

    klivitamJ 评论0 收藏0
  • [面试专题]JS异步Promise,Generator,Async

    摘要:所以,函数的一个重要实际意义就是用来处理异步操作,改写回调函数。表示在这里等待异步操作返回结果,再继续执行。 JS异步之Promise,Generator,Async Promise 解决的问题:回调地狱 Promise规范: promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从...

    xioqua 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<