ES6 - 初探 Promise(二)

简介: ES6 - 初探 Promise(二)

由于是同步回调,会阻塞后面的代码,如果fun2是个死循环,后面的代码就不执行了。

上一小节中setTimeout就是常见的异步回调,另外常见的异步回调即ajax请求。


/* 例2.4 */
/******************异步回调******************/
function request(url, param, successFun, errorFun) {
    $.ajax({
        type: 'GET',
        url: url,
        param: param,
        async: true,    //默认为true,即异步请求;false为同步请求
        success: successFun,
        error: errorFun
    });
}
request('test.html', '', function(data) {
    //请求成功后的回调函数,通常是对请求回来的数据进行处理
    console.log('请求成功啦, 这是返回的数据:', data);
},function(error) {
    console.log('sorry, 请求失败了, 这是失败信息:', error);
});


2.2、为什么使用Promise

说完了以上基本概念,我们就可以继续学习Promise了。


上面提到,Promise对象是用于异步操作的。既然我们可以使用异步回调来进行异步操作,为什么还要引入一个Promise新概念,还要花时间学习它呢?不要着急,下面就来谈谈Promise的过人之处。


我们先看看下面的demo,利用Promise改写例2.4的异步回调。


/* 例2.5 */
function sendRequest(url, param) {
    return new Promise(function (resolve, reject) {
        request(url, param, resolve, reject);
    });
}
sendRequest('test.html', '').then(function(data) {
    //异步操作成功后的回调
    console.log('请求成功啦, 这是返回的数据:', data);
}, function(error) {
    //异步操作失败后的回调
    console.log('sorry, 请求失败了, 这是失败信息:', error);
});

这么一看,并没有什么区别,还比上面的异步回调复杂,得先新建Promise再定义其回调。其实,Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。如果我们在第一次ajax请求后,还要用它返回的结果再次请求呢?

/* 例2.6 */
request('test1.html', '', function(data1) {
    console.log('第一次请求成功, 这是返回的数据:', data1);
    request('test2.html', data1, function (data2) {
        console.log('第二次请求成功, 这是返回的数据:', data2);
        request('test3.html', data2, function (data3) {
            console.log('第三次请求成功, 这是返回的数据:', data3);
            //request... 继续请求
        }, function(error3) {
            console.log('第三次请求失败, 这是失败信息:', error3);
        });
    }, function(error2) {
        console.log('第二次请求失败, 这是失败信息:', error2);
    });
}, function(error1) {
    console.log('第一次请求失败, 这是失败信息:', error1);
});

以上出现了多层回调嵌套,有种晕头转向的感觉。这也就是我们常说的厄运回调金字塔(Pyramid of Doom),编程体验十分不好。而使用Promise,我们就可以利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。

/* 例2.7 */
sendRequest('test1.html', '').then(function(data1) {
    console.log('第一次请求成功, 这是返回的数据:', data1);
    return sendRequest('test2.html', data1);
}).then(function(data2) {
    console.log('第二次请求成功, 这是返回的数据:', data2);
    return sendRequest('test3.html', data2);
}).then(function(data3) {
    console.log('第三次请求成功, 这是返回的数据:', data3);
}).catch(function(error) {
    //用catch捕捉前面的错误
    console.log('sorry, 请求失败了, 这是失败信息:', error);
});


是不是明显清晰很多?孰优孰略也无需多说了吧~下面就让我们真正进入Promise的学习。


三、Promise的基本用法

3.1、基本用法

上一小节我们认识了promise长什么样,但对它用到的resolve、reject、then、catch想必还不理解。下面我们一步步学习。


Promise对象代表一个未完成、但预计将来会完成的操作。


它有以下三种状态:


pending:初始值,不是fulfilled,也不是rejected

fulfilled:代表操作成功

rejected:代表操作失败

Promise有两种状态改变的方式,既可以从pending转变为fulfilled,也可以从pending转变为rejected。一旦状态改变,就「凝固」了,会一直保持这个状态,不会再发生变化。当状态发生变化,promise.then绑定的函数就会被调用。


注意:Promise一旦新建就会「立即执行」,无法取消。这也是它的缺点之一。


下面就通过例子进一步讲解。


/* 例3.1 */
//构建Promise
var promise = new Promise(function (resolve, reject) {
    if (/* 异步操作成功 */) {
        resolve(data);
    } else {
        /* 异步操作失败 */
        reject(error);
    }
});


类似构建对象,我们使用new来构建一个Promise。Promise接受一个「函数」作为参数,该函数的两个参数分别是resolve和reject。这两个函数就是就是「回调函数」,由JavaScript引擎提供。


resolve函数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;


reject函数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。


Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数。


/* 接例3.1 */
promise.then(onFulfilled, onRejected);
promise.then(function(data) {
  // do something when success
}, function(error) {
  // do something when failure
});

then方法会返回一个Promise。它有两个参数,分别为Promise从pending变为fulfilled和rejected时的回调函数(第二个参数非必选)。这两个函数都接受Promise对象传出的值作为参数。


简单来说,then就是定义resolve和reject函数的,其resolve参数相当于:

function resolveFun(data) {
    //data为promise传出的值
}
目录
相关文章
|
前端开发
理解 ES6 中的 Promise
【10月更文挑战第24天】ES6 中的 Promise 是一种用于处理异步操作的机制,它提供了一种更优雅、更可控的方式来处理异步任务的结果。Promise 可以看作是对异步操作结果的一种承诺,它可以处于三种不同的状态:Pending(等待中)、Fulfilled(已完成,即成功)和 Rejected(已拒绝,即失败)。
|
前端开发
手写实现ES6的Promise.all()和Promise.race()函数
这篇文章介绍了如何手写实现ES6的`Promise.all()`和`Promise.race()`函数,提供了实现这两个Promise聚合函数的详细代码示例,并展示了如何使用它们。
221 2
手写实现ES6的Promise.all()和Promise.race()函数
|
前端开发 JavaScript 小程序
JavaScript的ES6中Promise的使用以及个人理解
JavaScript的ES6中Promise的使用以及个人理解
172 1
|
前端开发 Java
说说你对es6中promise的理解?
说说你对es6中promise的理解?
90 1
|
前端开发 Java
说说你对es6中promise的理解?
说说你对es6中promise的理解?
|
前端开发 JavaScript
ES6新标准下JS异步编程Promise解读
ES6新标准下JS异步编程Promise解读
154 4
|
存储 前端开发 JavaScript
关于 ES6 中 Promise 的面试题
关于 ES6 中 Promise 的面试题
106 0
|
前端开发 JavaScript
ES6 中 Promise对象使用学习
ES6 中 Promise对象使用学习
132 1
|
JSON 前端开发 JavaScript
ES6引入Promise和async/await解决异步问题
【6月更文挑战第12天】ES6引入Promise和async/await解决异步问题。Promise处理异步操作,有pending、fulfilled、rejected三种状态,支持链式调用和并行处理。async/await是基于Promise的语法糖,使异步代码更同步化,提高可读性。两者都是处理回调地狱的有效工具,开发者应根据需求选择合适的方式。
156 3
|
前端开发 JavaScript
ES6新特性(五):Promise优雅地处理异步
ES6新特性(五):Promise优雅地处理异步