Promise

javascript是一个通过callback来处理异步的编程语言,而在有的情况下,我们需要回调的结果来作下一步的逻辑处理,而一层层的回调嵌套,会让我们陷入回调地狱中,而Promise可以帮我们解决这个问题。Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。

Promise对象

Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。

状态

一个Promise有以下状态:

  • pending: 初始状态
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

状态改变图:

image

Promise对象 - 属性

  1. Promise.length
    长度属性,总是为1(即为构造器参数的数量)
  2. Promise.prototype

Promise对象 - 方法

  1. Promise.all(iterable)
  • 参数iterable: 一系列的Promise对象
  • return:
    • 若iterable的所有Promise对象都触发成功 => 那么该Promise就会触发成功 => 并返回iterable的所有Promise的返回值(装在数组中,返回这个数组)。
    • 若iterable中有Promise触发失败 => 则该Promise就会触发失败 => 并返回iterable中第一个Promise的错误信息。
  1. Promise.race(iterable)
  • 参数iterable: 一系列的Promise对象
  • return: iterable中 最快成功的Promise的返回值/失败详情,然后返回新promise对象。
  1. Promise.resolve(value)
  • 参数value: (空,基本类型,一个promise对象) | 带有then方法的promise对象
  • return: 状态为fulfilled的Promise对象(并把value值传给then方法),可用作转化一个对象为Promise对象 | 由then方法执行决定

4. Promise.reject(reason)
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法

Promise对象 - 原型

属性

  1. Promise.prototype.constructor
    返回创建了实例原型的函数. 默认为 Promise 函数。

方法

  1. Promise.prototype.then(onFulfilled, onRejected)
    添加肯定和否定回调到当前 promise, 返回一个新的 promise, 将以回调的返回值 来resolve.
  2. Promise.prototype.catch(onRejected)
    添加一个否定(rejection) 回调到当前 promise, 返回一个新的promise。如果这个回调被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的肯定结果作为新promise的肯定结果

使用Promise

const myFirstPromise = new Promise((resolve, reject) => {
// 异步操作,最终调用:
//
//   resolve(someValue); // fulfilled
// 或
//   reject("failure reason"); // rejected
});

Promise 对象是由关键字new 及其构造函数来创建的
resolve 和 reject 作为其参数。
当异步任务顺利完成且返回结果值时,会调用 resolve 函数;
而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject 函数。

想要某个函数拥有promise功能,只需让其返回一个promise即可。

function myAsyncFunction(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.onload = () => resolve(xhr.responseText);
        xhr.onerror = () => reject(xhr.statusText);
        xhr.send();
    });
};

例子

基本例子

let myFirstPromise = new Promise(function(resolve, reject){
    //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
    //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
    setTimeout(function(){
        resolve("成功!"); //代码正常执行!
        reject("失败!"); //代码执行失败!
    }, 250);
});

myFirstPromise.then(function(successMessage, failMessage){
    //successMessage的值是上面调用resolve(...)方法传入的值.
    //failMessage的值是上面调用reject(...)方法传入的值.
    //successMessage参数不一定非要是字符串类型
    console.log("Yay! " + successMessage);
}).catch(reason => {
    console.log('Handle rejected promise ('+reason+') here.');// promise失败的回调
});

多个promise和并发

var num = 10;

function asyTimeOut(resolve, reject) {
    setTimeout(function() {
        console.log("保留技能,1s后再输出...");
        resolve(++num);
    }, 3000);
}

var result2 = new Promise(asyTimeOut);
result2.then(val => {
    console.log(val);
})


var result = new Promise(asyTimeOut);

result.then(function(val){
    console.log(val);
})

var totle = Promise.all([result,result,result2,result2]);

totle.then(t=>{
    t.map((num)=>{
        console.log(num);
    })
})

console.log('哈' + num);