美文网首页
Promise对象

Promise对象

作者: 撕心裂肺1232 | 来源:发表于2018-08-30 19:06 被阅读0次

1.概述

在JavaScript中,所有的代码都是单线程执行的,由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。Promise 对象是 JavaScript 的异步操作解决方案,为异步操作提供统一接口。Promise起到代理(proxy)的作用,使得异步操作具备同步操作的接口,Promise 可以让异步操作写起来,就像在写同步操作的流程,而不必一层层地嵌套回调函数。
异步执行可以调用回调函数实现:

function callback() {
    console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 1000); // 1秒钟后调用callback函数
console.log('after setTimeout()');

//控制台输出结果:
before setTimeout()
after setTimeout()
(等待1秒后)
Done

简单地说,异步操作会在将来的某个事件点触发一个函数调用。
ajax是典型的异步操作。以上一节的代码为例:

request.onreadystatechange = function () {
    if (request.readyState === 4) {
        if (request.status === 200) {
            return success(request.responseText);
        } else {
            return fail(request.status);
        }
    }
}

首先,Promise 是一个对象,也是一个构造函数。

function f1(resolve, reject) {
  // 异步代码...
}

var p1 = new Promise(f1);

Promise构造函数接受一个回调函数f1作为参数,f1里面是异步操作的代码。然后,返回的p1就是一个 Promise 实例
Promise 的设计思想是,所有异步任务都返回一个 Promise 实例。Promise 实例有一个then方法,用来指定下一步的回调函数。

// Promise
function f1(){
...
}
var p1 = new Promise(f1);
p1.then(f2);

传统的写法可能需要把f2作为回调函数传入f1,比如写成f1(f2),异步操作完成后,在f1内部调用f2。Promise 使得f1和f2变成了链式写法。不仅改善了可读性,而且对于多层嵌套的回调函数尤其方便。

step1(function (value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        // ...
      });
    });
  });
});

// Promise 的写法
(new Promise(step1))
  .then(step2)
  .then(step3)
  .then(step4);

2.Promise 对象的状态

Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

  • 异步操作未完成(pending)
  • 异步操作成功(fulfilled)
  • 异步操作失败(rejected)

状态变化:

  • 未完成 to 成功
  • 未完成 to 失败

Promise的最终结果:

  • 异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
  • 异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。

3.Promise 构造函数

var promise = new Promise(function (resolve, reject) {
  // ...

  if (/* 异步操作成功 */){
    resolve(value);
  } else { /* 异步操作失败 */
    reject(new Error());
  }
});

4. .then()

var p1 = new Promise(function (resolve, reject) {
  resolve('成功');
});
p1.then(console.log, console.error);
// "成功"

var p2 = new Promise(function (resolve, reject) {
  reject(new Error('失败'));
});
p2.then(console.log, console.error);
// Error: 失败

then()的用法:

f1().then(function () {            
  return f2();
}).then(f3);

//f3回调函数的参数,是f2函数的运行结果。
f1().then(function () {
  f2();
  return;
}).then(f3);

//f3回调函数的参数是undefined
f1().then(f2())
  .then(f3);

//f3回调函数的参数,是f2函数返回的函数的运行结果
f1().then(f2)
  .then(f3);

//f2会接收到f1()返回的结果,f3回调函数的参数,是f2函数的运行结果。

5. Promise的优势

Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了:


promise.png

Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。
串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码。有了Promise,我们只需要简单地写:

job1.then(job2).then(job3).catch(handleError);

除了串行执行若干异步任务外,Promise还可以并行执行异步任务
例如一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的用 Promise.all()实现

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 获得一个Array: ['P1', 'P2']
});

有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
    console.log(result); // 'P1'
});

//由于p1执行较快,Promise的then()将获得结果'P1'。p2仍在继续执行,但执行结果将被丢弃。

传送门

相关文章

  • Promise,async,await笔记

    Promise,async,await笔记 Promise 创建promise对象 Promise对象构造方法传入...

  • Promise then方法的链式调用

    返回的是非promise对象 优化:可能返回promise对象和非promise对象

  • ES6之promise(resolve与reject)

    一、 Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resol...

  • ES6-Promise对象 (下)

    ES6-Promise对象 (上) 1.Promise对象方法 (1)Promise.all(iterable);...

  • Promise对象原理解析

    Promise对象原理解析 ES6 原生提供了 Promise 对象。所谓 Promise,就是一个对象,用来传递...

  • ES6之promise(基本用法)

    一、promise的含义 Promise对象有以下两个特点。 (1)对象的状态不受外界影响。Promise对象代表...

  • Promise用法小结

    Promise 的含义 Promise对象有以下两个特点 :(1)对象的状态不受外界影响。Promise对象代表一...

  • 关于Promises

    一、名字 promise(首字母小写):一个对象,Promise的实例对象 Promise(首字母...

  • Promise

    Promise对象就是一个异步请求占位符对象 把异步请求封装在Promise对象中,Promise的构造函数传入一...

  • Promise

    Promise/A+ 英文 中文 实现Promise对象

网友评论

      本文标题:Promise对象

      本文链接:https://www.haomeiwen.com/subject/lazlwftx.html