Promise

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

如果一个 promise 已经"被兑现(fulfilled)"或"被拒绝(rejected)",那么我们也可以说它处于"已敲定(settled)"状态。

您还会听到一个经常跟 promise 一起使用的术语:"已决议(resolved)",任何不是 throw 的终止都会创建一个"已决议(resolved)"状态,而以 throw 终止则会创建一个"已拒绝(rejected)"状态。

链式调用

const myPromise = (new Promise(myExecutorFunc))
.then(handleFulfilledA)
.then(handleFulfilledB)
.catch(handleRejectedAny)
.finally(handleFinalAny);

自定义Promise

const promiseA = new Promise( (resolve,reject) =>{resolve(777);});
// 这时,"promiseA" 已经被敲定了。
promiseA.then( (val) => console.log("asynchronous logging has val:",val) );

构造函数

new Promise((resolve,reject)=>{})

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

静态方法

  1. all

    • 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的Promise。
    • 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise。
    • 其它情况下返回一个处理中(pending)的Promise。
  2. //注:Array,Map,Set都属于ES6的iterable类型

    Promise.all(iterable);
    const p1 = Promise.resolve(3),p2 = Promise.reject(4),p4 = 42,p5="42";
    const p3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 100, 'foo');
    });
    Promise.all([p1, p4, p3]).then((values) => {
    console.log(values);
    });
    Promise.all([p4, p5]).then((values) => {
    console.log(values);
    });
    p2.then(v=>{console.log(v);}).catch(e=>{
    console.log('error:',e);
    });
    /*
    > Array [42, "42"]
    > "error:" 4
    > Array [3, "foo", "foo"]
    */
  3. allsettled:返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

    Promise.allSettled(iterable);
    const p1 = Promise.resolve(1),p2 = Promise.reject(2);
    Promise.allSettled([p1,p2]).then((res) => console.log(res));
    //Array[Object{status: "fulfilled",value: 1},Object{status:"rejected",reason:2}]
  4. any:接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。

    Promise.any(iterable);
    const p1 = Promise.resolve(1),p2 = Promise.reject(2);
    Promise.any([p2,p1])
    .then((res) => console.log(res))
    .catch((e)=>console.log('error;',e));//1
  5. race:返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

    Promise.race(iterable);
    const p1 = Promise.resolve(1),p2 = Promise.reject(2);
    Promise.race([p2,p1])
    .then((res) => console.log(res))
    .catch((e)=>console.log('error;',e));//"error;" 2
  6. reject:返回一个带有拒绝原因的Promise对象。

    Promise.reject(reason);
  7. resolve:返回一个以给定值解析后的Promise 对象。

    Promise.resolve(value);

原型

方法
  1. then(onFufilled,onRejected):返回一个 Promise
  2. catch(onRejected):返回一个Promise (en-US),并且处理拒绝的情况。
  3. finally(onFinally):返回一个Promise。在promise结束时调用。
    • 由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况。

注意: 在finally回调中 throw(或返回被拒绝的promise)将以 throw() 指定的原因拒绝新的promise.

事件处理函数
  1. rejectionhandled:当Promise被rejected且有rejection处理器时会在全局触发rejectionhandled 事件(通常是发生在window下,但是也可能发生在Worker中)。应用于调试一般应用回退。

    window.addEventListener("rejectionhandled", event => {
    console.log("Promise rejected; reason: " + event.reason);
    }, false);
  2. unhandledrejection:当Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;这可能发生在 window 下,但也可能发生在 Worker 中。

    //onunhandledrejection(event:{promise,reason})
    window.addEventListener("unhandledrejection", event => {
    console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
    }); window.onunhandledrejection = event => {
    console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
    // 防止默认处理(例如将错误输出到控制台)
    event.preventDefault();
    };

Promise 与 async/await

function foo() {
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(`Got the final result: ${finalResult}`))
.catch(failureCallback);
} async function foo() {
try {
const result = await doSomething();
const newResult = await doSomethingElse(result);
const finalResult = await doThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) {
failureCallback(error);
}
}

旧式回调API

  1. setTimeout
    setTimeout(() => saySomething("10 seconds passed"), 10000);

问题:如果 saySomething 函数失败了,或者包含了编程错误,那就没有办法捕获它了。这得怪 setTimeout。

解决方法:可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们 解决方法:可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
wait(10000)
.then(() => saySomething("10 seconds")).catch(failureCallback);

组合Promise

  1. 多个并行

    Promise.all([func1(), func2(), func3()])
    .then(([result1, result2, result3]) => {
    /* use result1, result2 and result3 */
    });
  2. reduce时序

    [func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
    .then(result3 => { /* use result3 */ });
  3. Promise链

    Promise.resolve().then(func1).then(func2).then(func3);
  4. 函数式reduce时序

    const applyAsync = (acc,val) => acc.then(val);
    const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
  5. async/await时序

    let result;
    for (const f of [func1, func2, func3]) {
    result = await f(result);
    }

示例:() => x() => { return x; } 的简写。

doSomething()
.then(function(result) {return doSomethingElse(result);})
.then(newResult => doThirdThing(newResult))
.catch(error => console.log(error));

最新文章

  1. MongoDB集群配置
  2. Android Studio使用时源码到处报红色警告,运行时又没错
  3. jquery查找父元素、子元素(个人经验总结)
  4. Cloud Foundry 中国群英会【上海站、成都站】资料宣传
  5. Python基础知识拾遗
  6. Java继承时的初始化顺序
  7. ubuntu中vim下按上下左右键时输入A、B、C、D
  8. DevExpress.XtraGrid.GridControl中数据源的绑定问题
  9. PHPsocket、CURL、File_get_contents采集
  10. HBase 开发环境搭建(Eclipse\MyEclipse + Maven)
  11. Hadoop生态集群hdfs原理(转)
  12. JUnit4忽略(Ignore)测试实例
  13. 探索gff/gtf格式
  14. Hihocoder #1081 最短路径一 dijkstra
  15. Java Calendar Date使用总结
  16. 第三周JAVA程序设计基础学习总结
  17. June 22nd 2017 Week 25th Thursday
  18. 超过70亿条数据的mysql 去重
  19. Activiti入门 -- 轻松解读数据库
  20. oc的插件

热门文章

  1. windows下解决getAddressInfo Failed的一种办法
  2. 使用nvm实现自由切换nodejs版本
  3. zzul1073_Java
  4. [人脸识别]01-python环境准备-安装opencv
  5. JS中立即执行函数和闭包的区别
  6. transform2d转换、transition过渡、animation动画效果、@keyframes定义动画关键帧
  7. ASPNETCORE托管/部署到WindowService的问题[服务显示正在启动]
  8. Vue中v-if和v-for一起使用时的优先级
  9. Fortran处理无符号整型unsigned integer
  10. C与C++字符串比较