WinJS.Promise探索

今天我们来研究下WinJS库中的WinJS.Promise,这个东西是干什么用的呢?msdn给的翻译是承诺,不知道你们能不能理解,反正我第一次听到时是一头雾水,换一种说法,叫做“异步编程”,应该能明白吧!举个例子,你要下载一张图片,如果不用异步的话,当你开启一个线程下载时,这个线程会一载等待,直到该图片下载完成,如果使用异步编程的话,当你开启一个线程下载时,会发送一个下载图片的请求,然后继续执行该方法之后的代码,当图片开载完成后,你可以在指定的地方接收到下载完成的信息。

一:Promise

我们首先来看一个不用Promise的例子:

function withoutPromise() {
        var totalSize = computedWithoutPromise();
    }

    function computedWithoutPromise() {
        setTimeout(function () {
            var count = 10000;
            var totalSize = 0;

            for (var i = 0; i < count; i++) {
                totalSize += i;
            }

            return totalSize;
        }, 2 * 1000);
    }

一个computedWithoutPromise方法,该方法计划在2秒后执行,如果按照以上方式进行调用的话,那么你的totalSize得到的值是undefined,如果你想在computedWithoutPromise方法里面的return totalSize之后,让调用者得到结果应该怎么办呢?这时就可以使用Promise,如下代码所示:

 function withPromise() {
        computedWithPromise().then(function (totalSize) {
            var result = totalSize;
        });
    }

 function computedWithPromise() {
        return new WinJS.Promise(function (onComplete, onError) {
            setTimeout(function () {
                var count = 10000;
                var totalSize = 0;

                for (var i = 0; i < count; i++) {
                    totalSize += i;
                }
                onComplete(totalSize);
            }, 2 * 1000);
        });
    }

分析代码发现该写法和第一种写法有两个地方不同

1:computedWithPromise内部:在computedWithPromise方法内部,用return new WinJS.Promise(function(oncomplete,onError){});代码片断把setTimeout()给包起来了。

2:在omputedWithPromise调用的地方,不是直接将该方法写在一个变量之后,而是用.then(function(totalSize){})来进行调用。

好了,我们来分析一下,用WinJS.Promise把代码包起来,表示将该方法作为一个异步方法进行执行,.then(function(totalSize)}{)表示注册一个回调,当异步方法执行完成后,执行该方法,也就是该方法执行完成之后会以某种方式将结果返回给调用者,在本例中是computedWithPromise().then(function(totalSize))会在onComplete(totalSize)之后接收到通知,从而得到结果。也就是说在调用computedWithPromise().then(function(totalSize){})中,totalSize代表computedWithPromise返回的结果,虽然computedWithPromise是一个异步方法。

如果你把调用代码改成:

function withPromise() {
        computedWithPromise().then(function (totalSize) {
            var result = totalSize;
        });
        var a = "abc";
    }

则可以看到computedWithPromise执行完后会先执行var a="abc";再执行var result=totalSize;这就是异步,这个类似于.net中的委托。

我们来重新组合一下代码,如下所示:

function withoutPromise() {
        var totalSize = computedWithoutPromise();
    }

    function withPromise() {
        computedWithPromise().then(function (totalSize) {
            var result = totalSize;
        },function(error){

             console.log(error);

       });
        var a = "abc";
    }

    function computedWithoutPromise(onComplete) {
        setTimeout(function () {
            var count = 10000;
            var totalSize = 0;

            for (var i = 0; i < count; i++) {
                totalSize += i;
            }

            if (onComplete) {
                onComplete(totalSize);
                return;
            }

            return totalSize;
        }, 2 * 1000);
    }

    function computedWithPromise() {
        return new WinJS.Promise(function (onComplete, onError) {
            computedWithoutPromise(onComplete);
        });
    }

注意:

1,如果在omputedWithPromise没有调用onComplete,则在调用的地方永远不会接收到信息。

2,当异步方法执行失败时会走error的回调方法。

如果说项目中有这样一个需求:用户登录后会去服务端进行验证,验证成功后获取用户的好友列表,那么你可以这样做:

validateUser().then(function(userInfo){return getFriensList(userInfo.userID);}).then(function(friendsList){});

promise还可以这样用:

function getFriendsList(){

 return new WinJS.Promise(function(onComplete,onError){

      onComplete("friends list.");

})

}

function parseFriensList(){

return getFreindsList().then(function(friendsList){//getFriendsList是一个Promise

      return friendsList

});

}

function getFriendsList(){

    parseFriendsList().then(function(friendsList){//this frienslist has been parsed.

    

})

}


二,Promise.join

Promise.join是有什么用处呢?

Promise.join可以把一系列promise组合起来,等到所有promise全部完成之后再执行then后面的语句,举个例子来说明一下:

如果有这个一个需求:一个音乐播放器要下载歌曲和歌词,歌曲和歌词两个全部下载完成后会立即进行歌曲的播放并且显示歌词。

你开始的思路可能是有两个不同的promise,然后声明一个变量,在两个不同的promise完成之后对变量进行判断来确定歌曲和歌词是否全部下载完成。其实完全没必要这样做,这时你可以使用Promise.join。

下面用一个实际的例子来说明一下:

function promiseJoin() {
        var downloadSongPromise = downloadSongAsync();
        var downloadLyricsPromise = downloadLyricsAsync();

        var promise = [downloadSongPromise, downloadLyricsPromise];

        WinJS.Promise.join(promise).then(function (result) {
            var a = result;
        });
    }

    function downloadSongAsync() {
        return new WinJS.Promise(function (onComplete, onError) {
            setTimeout(function () {
                onComplete("the song has downloaded completed.");
            }, 5 * 1000);//after 5 seconds then return the result.
        });
    }

    function downloadLyricsAsync() {
        return new WinJS.Promise(function (onComplete, onError) {
            setTimeout(function () {
                onComplete("the lyrics has downloaded completed.");
            }, 2 * 1000);
        });
    }

WinJS.Promise.join(promise)表示要等promise数组中的所有promise执行完成之后才执行,result是一个数组,resule[0]代表promise中的第一个promise返回的结果,result[1]代表promise中的第二个promise返回的结果,依次类推。

三,Promise.as

Promise.as有什么作用呢,是次一个非promise转换为一个Promise,应用场景举例:

接上例,在下载歌曲和歌词时,会先从缓存读取,如果缓存中没有则在从网络下载。

改造后的代码如下:

function promiseJoin() {
        var downloadSongPromise = downloadSongAsync();
        var downloadLyricsPromise = downloadLyricsAsync();

        var promise = [downloadSongPromise, downloadLyricsPromise];

        WinJS.Promise.join(promise).then(function (result) {
            var a = result;
        });
    }

    function downloadSongAsync() {
        var cacheSong = readLoadData("song_cache");
        if (cacheSong)
            return WinJS.Promise.as(cacheSong);
        else {
            return new WinJS.Promise(function (onComplete, onError) {
                setTimeout(function () {
                    onComplete("the song has downloaded completed.");
                }, 5 * 1000);//after 5 seconds then return the result.
            });
        }
    }

    function downloadLyricsAsync() {
        var cacheLyrics = readLoadData("lyrics_cache");
        if (cacheLyrics)
            return WinJS.Promise.as(cacheLyrics);
        else {
            return new WinJS.Promise(function (onComplete, onError) {
                setTimeout(function () {
                    onComplete("the lyrics has downloaded completed.");
                }, 2 * 1000);
            });
        }
    }

    function readLoadData(cacheKey) {
        return cacheKey;
    }

四,Promise.timeout

顾名思义,Promise.timeout是处理超时用的,timeout的语法是

Promise.timeout(timeout,promise).then(function(){

//execute your code

},function(error){

//execute timeout event handler

})

当你的promise的执行时间超过Promise.timieout的timeout设定的时候时,会走error回调函数。如下代码所示:

 function promiseTimeout() {
        var downloadSongPromise = downloadSongAsync();
        var downloadLyricsPromise = downloadLyricsAsync();

        var promise = [downloadSongPromise, downloadLyricsPromise];

        WinJS.Promise.timeout(3 * 1000, WinJS.Promise.join(promise)).then(function (result) {
            var a = result;
        }, function (error) {
            console.log(error);
        });
    }


还有一些其它的方法,像cancel,wrap等等,提供一个msdn学习网址:http://msdn.microsoft.com/zh-cn/library/windows/apps/br211867.aspx

demo下载地址:

http://yunpan.cn/QD5ZuWsvMdFcS

欢迎指正

谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
### 回答1: Windows.UI.Popups 命名空间包含用于创建弹出对话框的类。如果要在 JavaScript 中使用这个命名空间,可以使用以下方法之一: 1. 在 HTML 中使用 script 标签引入 Microsoft.WinJS 库。在使用 Windows.UI.Popups 命名空间之前,需要在代码中加载 Microsoft.WinJS 库。 ```html <script src="/js/winjs/base.js"></script> ``` 2. 在 JavaScript 代码中使用 require 函数引入 Windows.UI.Popups 命名空间。 ```js var popups = require("Windows.UI.Popups"); ``` 3. 在 JavaScript 代码中使用 ECMAScript 6 的 import 语句引入 Windows.UI.Popups 命名空间。 ```js import { MessageDialog } from "Windows.UI.Popups"; ``` 注意:这些方法仅适用于在 Windows 应用中使用 JavaScript。如果您的 JavaScript 代码是用于 Web 应用或其他非 Windows 应用程序,则不能使用 Windows.UI.Popups 命名空间。 ### 回答2: 要引入Windows.UI.Popups命名空间,在js中可以使用以下步骤: 首先,在你的JavaScript文件的开头添加以下代码: ```javascript import { MessageDialog } from 'Windows.UI.Popups'; ``` 这行代码将会导入Windows.UI.Popups命名空间中的MessageDialog类。 接下来,在你的代码中就可以使用MessageDialog类来创建一个弹窗对话框了。例如,以下是创建一个简单的弹窗对话框并显示的代码: ```javascript var dialog = new MessageDialog("欢迎使用这个应用程序!"); dialog.showAsync(); ``` 上述代码会创建一个MessageDialog对象,并将一条欢迎消息作为参数传递给构造函数。然后,使用showAsync()方法来显示对话框。 需要注意的是,在引入Windows.UI.Popups命名空间之前,你需要确保你的代码是在Windows环境下运行的,因为Windows.UI.Popups命名空间是在Windows系统上才可用的。 希望这些信息对你有帮助! ### 回答3: 要引入Windows.UI.Popups命名空间,你可以通过在JavaScript文件的开头使用import语句来实现。在引入命名空间之前,确保在你的Windows应用项目中已正确添加了Windows.UI.Popups命名空间的引用。 在JavaScript文件的开头,使用以下语法来引入命名空间: import Windows.UI.Popups; 这将使得Windows.UI.Popups命名空间下的所有类、方法和属性都能在当前的JavaScript文件中使用。 注意:在引入命名空间之前,你需要确保你的Windows应用项目已正确添加了Windows.UI.Popups命名空间的引用。确保在你的项目文件夹中的References或Dependencies目录下能找到Windows.UI.Popups。如果没有找到,你需要手动添加该引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值