zoukankan      html  css  js  c++  java
  • Promise

    Promise

    参考
    http://lucifier129.github.io/nodeppt/20150528/promise.htm
    http://efe.baidu.com/blog/promises-anti-pattern/
    http://www.html5rocks.com/zh/tutorials/es6/promises/#toc-api

    使用浏览器的Promise

    将一个非Promise变成Promise

        function get(url) {
            // 返回一个新的 Promise
            return new Promise(function(resolve, reject) {
                // 经典 XHR 操作
                var req = new XMLHttpRequest();
                req.open('GET', url);
    
                req.onload = function() {
                    // 当发生 404 等状况的时候调用此函数
                    // 所以先检查状态码
                    if (req.status == 200) {
                        // 以响应文本为结果,完成此 Promise
                        resolve(req.response);
                    } else {
                        // 否则就以状态码为结果否定掉此 Promise
                        // (提供一个有意义的 Error 对象)
                        reject(Error(req.statusText));
                    }
                };
    
                // 网络异常的处理方法
                req.onerror = function() {
                    reject(Error("Network Error"));
                };
    
                // 发出请求
                req.send();
            });
        }
        story = get('story.json');
        story.then(function(res){
            return JSON.parse(res);
        }).then(function(obj){
            console.log(obj);
        });
    

    再来一个例子
    我把ajax的例子放在前面是因为我觉得 ajax的使用场景会更容易理解

        var getData = function(){
            var data;
            setTimeout(function(){
                data = 'data';
            },0);
            return data;
        }
        console.log(getData()); //undefined //显然这样是得不到结果的
        //所以我们必须传入一个回调函数
        var getData = function(callback){
            var data;
            setTimeout(function(){
                data = 'data';
                callback(data);
            },0);
        }
        getData(function(data){
            console.log(data)
        });
    

    改成Promise

        var getData = function(){
            var promise = new Promise(function(resolve, reject){
                setTimeout(function(){
                    resolve('data');
                },0);
            });
            return promise;
        }
        getData().then(function(data){
            console.log(data);
        });
    
    

    关于defer

    下面是用Q.js 的defer

    http://efe.baidu.com/blog/promises-anti-pattern/ 这里建议不在使用defer
    尽管这个写法在https://github.com/kriskowal/q 中可以看到

        function load(url) {
            var deferred = Q.defer();
            var req = new XMLHttpRequest();
            req.onreadystatechange = function() {
                if (req.readyState === 4) {
                    deferred.resolve(req.responseText);
                }
            }
            req.open('GET', url, true);
            req.send();
            return deferred.promise;
        }
        load('story.json').then(function(data) {
            console.log(data);
        });
    

    最好这么用 (这里实际上就是告诉你如何用Q.js包装出一个Promise)
    原文中有这么一句

    Q.Promise
    This is an alternative promise-creation API that has the same power as the deferred concept, but without introducing another conceptual entity.

        function load(url){
            return Q.Promise(function (resolve, reject) {
                var req = new XMLHttpRequest();
                req.onreadystatechange = function() {
                    if (req.readyState === 4) {
                        resolve(req.responseText);
                    }
                }
                req.open('GET', url, true);
                req.send();
            });
        }
        load('story.json').then(function(data) {
            console.log(data);
        });
    

    链式操作

    比如我需要等意见事情做完了再做另一件事情
    最容易想到的

        get('story.json').then(function(data){
            get('story.txt').then(function(data2){
                get('xxx').then(function(data3){
                    //.....
                })
            })
        });
    

    突然觉得不对 不是说Promise是用来解决嵌套的问题嘛 这看起来还是在嵌套啊

    我们需要return一个promise对象 这才是真正解决深层嵌套

        get('story.json').then(function(data){
            return get('story.txt');
        }).then(function(rs){
            console.log(rs); //虽然前一个Promise返回的是一个Promise对象  但是这里的rs并不是一个Promise  而是前面的Promise对象resolve的结果 //也就是story.txt中的内容
            return get('xxx');
        }).then(function(xxx){
            return get('dot');
        }).then(function(dot){
            //...
        })
    

    当然了 假如你需要某次回调中得到所有异步的结果 你可以用第一种嵌套形式
    或者使用Promise.all

    Promise.all

        var p1 = Promise.resolve(1),
            p2 = Promise.resolve(2),
            p3 = Promise.resolve(3);
        Promise.all([p1, p2, p3]).then(function (results) {
            console.log(results);  // [1, 2, 3]
        });
        //Promise.all 常用在 forEach 中
        //比如
        get('story.json').then(function(story){
            var promiseArr = story.chapters.map(function(chapter){
                return get(chapter.url);
            });
            return Promise.all(promiseArr);
        }).then(function(resultsArr){
            //resultsArr 是一个数组
        })
    
    

    再来一个例子 这里使用的是q.js 中的Promise all

        var promises = urls.map(function(url){
            return Q.promise(function(resolve, reject){
                superagent.get(url).end(function(err,res){
                    resolve({
                        url: url,
                        text: res.text
                    });
                });
            });
        });
        Q.all(promises).then(function(arr){
            arr = arr.map(function(item){
                var $ = cheerio.load(item.text);
                return {
                    href: item.url,
                    title: $('.topic_full_title').html() ? $('.topic_full_title').html() : '',
                    comment: $('.reply_content').eq(0).text() ? $('.reply_content').eq(0).text() : ''
                }
            });
            console.log(arr);
        })
    
  • 相关阅读:
    ASP.NET里面,如果设置了form的 onsubmit="return false;"之后,就不能提交按钮了?
    存储过程(待填)
    关于电脑屏幕分辨率太高字太小怎么解决?
    最新版Android开发工具
    Xamarin For Visual Studio 3.0.54.0 完整离线破解版(C# 开发Android、IOS工具 吾乐吧软件站分享)
    ubuntu 16.04 source (HUST and 163)
    transmission简单使用
    Test Tex
    What is a Statistic?
    IDE、SATA、SCSI、SAS、FC、SSD硬盘类型介绍[zz]
  • 原文地址:https://www.cnblogs.com/cart55free99/p/4732662.html
Copyright © 2011-2022 走看看