Promise 汇总

故事扮演 提交于 2020-03-02 10:43:24

1、概念

Promise 表示一个异步操作的最终结果。

可以将Promise理解为一个状态机,它存在下面三种状态,并在某一时刻只能有一种状态:

Pending : 表示还在执行

Fulfilled(或resolved):执行成功

Rejected:执行失败。

一个Promise是对一个操作(通常是一个异步操作)的封装,异步操作有等待完成、成功、失败三种可能结果,对应了Promise三种状态。

 

例子:读取文件


let fs = require('fs');

let readFile_promise = (path) => {
    return new Promise((resolve,reject) => {
        fs.readFile(path,"UTF-8",(err,data) => {
            if(data){
                resolve(data);
            }else{
                reject(err)
            }
        })
    })
}

//使用then方法接受数据
readFile_promise("./11.html").then((data) => {
    console.log("succ:",data);
},(err) => {
    console.log("err:",err);
})


//使用catch() 捕捉错误,效果和上面一样!
readFile_promise("./11.html").then((data) => {
    console.log("succ:",data);
}).catch((err) => {
    console.log("文件读取错误!",err);
})

then的用法:

第一个then方法中,再次调用了read_ promise,其返回的新的Promise覆盖了默认返回的Promise,我们因此可以在下一个then方法中获取另一个异步操作的执行结果。

 


let fs = require('fs');

let readFile_promise = (path) => {
    return new Promise((resolve,reject) => {
        fs.readFile(path,"UTF-8",(err,data) => {
            if(data){
                resolve(data);
            }else{
                reject(err)
            }
        })
    })
}

//使用then方法接受数据
readFile_promise("./1.html").then((data) => {
    console.log("succ:",data);
    return readFile_promise("./a1.html");   //发起第二次读取
},(err) => {
    console.log("第一次读取err:",err);
}).then((data) => {
    console.log("data:",data);
},(err) => {
    console.log("第二次读取err: ",err);
})

虽然通过then获取promise的结果,Promise从被创建的那一刻起就开始执行,then方法只提供了访问Promise状态的接口,与Promise无关。

 

 

二、Promise的常用接口

2.1  Promise.resolve  用来将一个非Promise对象转化为Promise对象,

注意:resolve方法不能转换异步方法。


let fs = require('fs');

let readFile_promise = (path) => {
    return path;
}

Promise.resolve(readFile_promise("hello,world")).then((data) => {
    console.log("data: ",data);   //data: hello,world
})


//注意: Promise.reslove()  不能包裹一个异步函数
//或许读者想着可以使用resolve来转换一个异步方法,例如readFile之类的,很遗憾resolve方法做不到这一点,下面代码是无法执行的:

let fs = require('fs');

let readFile_promise = (path) => {
    fs.readFile(path,"UTF-8",(err,data) => {
        if(data){
            return data;
        }else{
            return err;
        }
    })
}

Promise.resolve(readFile_promise("./1.html")).then((data) => {
    console.log("data");
})

2.2 promise.reject()  

返回一个promise对象,promise状态为reject,方法参数会将参数作为错误信息传递给then方法。

let readFile_promise = (param) => {
    return param;
}

Promise.reject(readFile_promise("hello,world")).then((data) => {
    console.log("data: ",data);   //data: hello,world
})

 

2.3  Promise.all

Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。

Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。

let fs = require('fs');

let readFile_promise = (path, time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            fs.readFile(path, "UTF-8", (err, data) => {
                if (data) {
                    resolve(data);
                } else {
                    reject(err)
                }
            })
        }, time)

    })
}
let p1 = readFile_promise("./1.html",3000);
let p2 = readFile_promise("./a.html",1000)

//使用then方法接受数据,所有resolve,才会resolve;有一个reject,就reject
Promise.all([p1, p2]).then((data) => {
    console.log("succ:", data);
}, (err) => {
    console.log("err:", err);
})

//注意的是,
//Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,
//即p1的结果在前,即便p1的结果获取的比p2要晚。


需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

 

2.4 promise.race

race返回的Promise的状态由数组中率先执行完毕的Promise的状态决定

Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let fs = require('fs');

let readFile_promise = (path, time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            fs.readFile(path, "UTF-8", (err, data) => {
                if (data) {
                    resolve(data);
                } else {
                    reject(err)
                }
            })
        }, time)

    })
}
let p1 = readFile_promise("./1.html",3000);
let p2 = readFile_promise("./a.html",1000)

//谁先执行完成,返回谁,无论对错
Promise.race([p1, p2]).then((data) => {
    console.log("succ:", data);
}, (err) => {
    console.log("err:", err);
})

 

第三方库:bluebird

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!