zoukankan      html  css  js  c++  java
  • Promise

    基础语法
    http://es6.ruanyifeng.com/#docs/promise
    点评:
    》注意理解Promise定义形式和调用形式的差别,定义时主要指定什么情况下(比如去后台查询到数据)可以resolve或reject,调用时通过then指定resovle状态下执行什么回调方法,从而避免传统的回调写法层次太深的陷阱。
    》注意理解执行顺序,Promise 定义时立即执行,且此时调用resolve或reject方法不会阻止后续代码的执行,而then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,即在本轮事件循环的末尾执行。
    let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    resolve();
    console.log('Promise end');
    });
    promise.then(function() {
    console.log('resolved.');
    });
    console.log('Hi!');
    输出为:
    // Promise
    // Promise end
    // Hi!
    // resolved
    》Promise对象触发resolve回调方法(即then绑定的参数)的调用是内部状态化,这个变化可以是主动的(调用resolve(参数是普通的值)),也可以是被动的(调用resolve(参数为另一个Promise对象)),这时其内部状态受另一个Promise对象的内部状态的影响。

    》Promise内部状态一旦变为Fullfilled就不会再变,且then绑定的两个回调方法中返回的值,会自动包装成一个已resolved的promise,从而会传递给链式绑定的下一个then方法的成功回调函数里面去,并且上一个then回调函数返回的数据可被下一个then的回调函数接收。因此,不要在then方法里面定义 reject 状态的回调函数(即then的第二个参数),总是使用catch方法。因为reject回调中throw的error也是resolved状态而catch不住,除非不是throw new Error('error!!!')而是return Promise.reject(new Error('error!!!'))。详细分析参见下面的“最佳实践”。
    // good
    promise
    .then(function(data) { //cb
    // success
    return newdata // 这里返回的数据可被下一个then回调接收
    })
    .then(function(data) { //cb
    // success
    })
    .catch(function(err) {
    // error
    });
    注意Node目前如果没有使用catch方法指定错误处理的回调函数,Promise对象抛出的错误不会传递到外层代码,即不会有任何反应。未来Node有计划如果 Promise 内部有未捕获的错误,会直接终止进程。
    一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误。catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。

    》有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。
    Promise.resolve()等价于下面的写法。
    Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))

    Promise.resolve方法的参数分成四种情况。
    (1)参数是一个 Promise 实例
    如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

    (2)参数是一个thenable对象
    Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
    let thenable = {
    then: function(resolve, reject) {
    resolve(42);
    }
    };

    let p1 = Promise.resolve(thenable);
    p1.then(function(value) {
    console.log(value); // 42
    });
    上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。

    (3)参数不是具有then方法的对象,或根本就不是对象
    如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。
    const p = Promise.resolve('Hello');
    p.then(function (s){
    console.log(s)
    });
    // Hello
    上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。

    (4)不带有任何参数
    Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

    同理,Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

    异步加载图片示例:
    const getJSON = function(url) {
    const promise = new Promise(function(resolve, reject){
    const handler = function() {
    if (this.readyState !== 4) {
    return;
    }
    if (this.status === 200) {
    resolve(this.response);
    } else {
    reject(new Error(this.statusText));
    }
    };
    const client = new XMLHttpRequest();
    client.open("GET", url);
    client.onreadystatechange = handler;
    client.responseType = "json";
    client.setRequestHeader("Accept", "application/json");
    client.send();

    });

    return promise;
    };

    getJSON("/posts.json").then(function(json) {
    console.log('Contents: ' + json);
    }, function(error) {
    console.error('出错了', error);
    });

    》Bluebird 是一个功能丰富而且性能优异的 Promise 实现
    https://www.ibm.com/developerworks/cn/web/wa-lo-use-bluebird-implements-power-promise/index.html

    最佳实践
    https://segmentfault.com/a/1190000014747362?utm_source=tag-newest

  • 相关阅读:
    个人管理:提高你的搜商
    敏捷个人:提供更多文档下载,并转载一篇敏捷个人读书笔记
    个人管理: 激励你的一句话
    敏捷个人 从Scrum实践来思考如何导入价值观
    信息系统开发平台OpenExpressApp 如何解决ComboBox.TextProperty绑定带来问题的来龙去脉
    敏捷个人 敏捷个人价值观,欢迎提出你的意见和你的价值观
    使用VS2010的CodedUI来做自己的自动化测试框架
    .Net4下的MEF(Managed Extensibility Framework) 架构简介
    IronRuby - 快速在半小时学习Ruby基础知识
    敏捷个人 项目网站文档页签增加blog链接
  • 原文地址:https://www.cnblogs.com/ccdat/p/11711348.html
Copyright © 2011-2022 走看看