初学 WinJS, 可能对 Promise 的用法不大清楚,本文简要说明一下 WinJS中 promise 的基本用法。
主要参考自:http://try.buildwinjs.com/#promises
Promise是 WinJS中实现异步模式编程的实现形式,
它其实更多的是一种规范,用来规范和简化 javascript 中的异步编程。
在promise被提出来之前,javascript中的异步编程通常是直接使用回调来完成的。
1
2
3
4
5
6
7
|
var getParentList = function (getParentListCallback) {
// do get parent list data cost about 1 or more seconds
// ...
var parentList = XXX;
// when get the data sucessfully, call the callback
getParentListCallback(parentList);
} |
使用的时候,就是这样的:
getParentList( function getParentListCallback(parentList) {
// get children data according to the parentList data
for ( var i = 0; i < parentList.length; i++) {
//
getChildrenList(parentList[i]);
}
}); |
一个函数执行可能会花费比较长的时间,逻辑上不需要等待这个函数返回,就可以执行后面的代码,
这是非常常见的场景,使用上面回调函数的方法,完全可以解决问题。
但如果场景更复杂一些,或者需要考虑更多的情况,例如异常处理,根据不同的返回值,调用不同的回调函数,
就会发现这种写法非常的ugly。如果有三层回调的话,代码可能是这样的:
getParentList( // success callback
function getParentListCallback(parentList) {
// get children data according to the parentList data
for (var i = 0 ; i < parentList.length; i++) {
//
getChildrenList(parentList[i],
// success callback
function getChildrenListCallback(childrenList) {
for (var j = 0 ; j < childrenList.length; j++) {
getChildDetail(childrenList[j],
// success callback
function getChildDetailCallback(detailInfo) {
},
// error callback
function errorCallback() {
})
}
},
// error callback
function errorCallback() {
});
}
},
// error callback
function errorCallback() {
// Do something to handle the error
}
); |
感觉如何?同一逻辑的的suc和error隔着很多其它的代码,代码的嵌套层次还特别深,
这还是在大部分逻辑没有展开的情况下看到的样子呢,如果在实际项目中使用,逻辑全部展开,最终的代码估计自己写完都不想再看第二遍。
OK,promise来了,promise有个 Promises/A+ 实现规范,有兴趣的可以抽时间看下。
现在,我们直接看下使用 promise 后的代码:
getParentList() .then(
function (parentList) {
var promiseArray = [];
for ( var i = 0; i < parentList.length; i++) {
promiseArray.push(getChildrenList(parentList[i]));
}
return promiseArray.join();
},
function error() {
})
.then(
function (chilrenList) {
var promiseArray = [];
for ( var i = 0; i < chilrenList.length; i++) {
promiseArray.push(getChildDetail(chilrenList[i]));
}
return promiseArray.join();
},
function error() {
})
.done(
function (detailInfo) {
},
function error() {
});
|
直观上看,promise让原来的代码嵌套层次少了,更加扁平可读了,而且逻辑功能上的suc和err处理放到一起了。
但 promise 并不仅仅这么简单。
个人理解,promise把原来的函数之间的嵌套调用,演化成了链式的关系。
.then ... .then 做为链中的一环,直到 .done,表示到了链的最后一环。(.done仅仅表明不再向后链接了,并不强制要求使用。)
所以说, promise其实本质上是一种规范,或者说是一种编程模式。
对于这个模式,各基于 javascript 的开发工具都有自己的实现,像 WinJS, NodeJs等。
WinJS的的 promise 是如何使用的呢?
首先,创建一个 promise:
项目开发中,对于比较耗时的操作,通常通过如下形式创建 promise 来执行:
// Do an add asynchronously (via setTimeout) function asyncAdd(num1, num2) {
return new WinJS.Promise( function (complete) {
setTimeout( function () {
var sum = num1 + num2;
// this promise is completed when the complete() function is called which also
// returns the value (result) of the promise.
complete(sum);
}, 1000);
});
} |
这样,使用时,即可如下使用:
asyncAdd(1, 2). then( function (v) {
// 此处,v === 3
})
|
然后,我们可能已经有了一个同步执行的函数,如何让它以promise的形式来调用它呢?
如下进行:
// add two numbers together synchronously function nonPromiseAdd(num1, num2) {
return num1 + num2;
} // wrap the regular non-synchronous method in Promise.as() to treat it as a promise WinJS.Promise.as(nonPromiseAdd(3, 4)). then( function (v){
// 此处,v === 7
}); |
好,接下来的功能,就是 promise的强大之外了。
-
promise之 cancel。 异步操作时,通常会遇到上下文,或者说场景,context已经失效了,异步操作还没有完成,或者异步操作完成了,但context失效,已经没有意义了。相信大家都有自己的解决方法。使用 promise的话,很简单,直接把 promise cancel掉就行了。
var
loadImagePromise = WinJS.Promise.as(loadImage());
function
unload() {
loadImagePromise.cancel();
}
有一点需要注意的是,promise执行过程中被cancel掉的话,promise.then会被调用,这时候需要判断 promise的状态,promise._state.name 的值,可能是success,或者是canceled。
-
promise之join。多个异步操作同时执行的话,就会有异步操作之前协调的问题。promise.join提供一个promise的数组做参数,表示这个数组中的所有promise都执行完成后,promise.join才会视为执行完成,即 promise.join(promiseArray).then(){}中的then才会被执行。
var
p = [];
var
index = 0;
// create a promise that completes in 2000ms, then add it to the promise array
p[index++] = WinJS.Promise.timeout(2000).
then(
function
() {
output(
"<br/> First promise is fullfilled after 2 seconds"
);
}
);
// create a promise that completes in 3000ms, then add it to the promise array
p[index++] = WinJS.Promise.timeout(3000).
then(
function
() {
output(
"<br/> Second promise is fullfilled after 3 seconds"
);
}
);
// pass the promise array to Promise.join() to create a promise that will not be completed until all
// promises have been completed.
WinJS.Promise.join(p).
then(
function
() {
output(
"<br/> Calling join will ensure this function will not be called until the both promises have been completed."
);
});
- promise之any。同上类似的场景,如果要求 promise数组中,任意一个promise执行完成即可的话,就使用promise.any。
OK,上面仅是 WinJS支持的 promise功能。由于 javascript的开源特性,很多其它基于js的工具包中的 promise,是可以直接拿来使用的(在遵守开源许可的情况下,把代码引入到我们的项目中即可)。所以我们可以非常方便的使用诸如 NodeJS里面的promise功能。为什么要使用他们的呢,他山之石,可以攻玉,比如我们项目中常用的 Async.js (https://github.com/caolan/async),是为NodeJS设计使用的,但它没有第三方依赖,实现代码只有一个 js 文件,可以直接引用,它的promise提供以下常用功能(仅列举常用,详细请参数 Anync.js的 github 网站):
-
async.each。async不需要手动创建promise,它支持直接以数组为参数。async.each的函数原型如下:
each(array, functionForEachItem, errorCallback)
针对每个 array里面的item, 都会执行一次functionForEachItem, 使用起来是这样的:
// assuming openFiles is an array of file names
async.each(openFiles,
function
( file, callback) {
// Perform operation on file here.
console.log(
'Processing file '
+ file);
if
( file.length > 32 ) {
console.log(
'This file name is too long'
);
callback(
'File name too long'
);
}
else
{
// Do work to process file here
console.log(
'File processed'
);
callback();
}
},
function
(err){
// if any of the file processing produced an error, err would equal that error
if
( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log(
'A file failed to process'
);
}
else
{
console.log(
'All files have been processed successfully'
);
}
});
- async.eachSeries. 同each类似,但是eachSeries可以保证针对每个 array里面的item, 执行functionForEachItem是顺执行,且只有前面的item执行完成,才会执行后面的item。
async提供很多其它方便的功能,请大家https://github.com/caolan/async 了解更多,仔细查看,你会有一种只有想不到,没有做不到的感觉。
[WinJS] Promise 用法的更多相关文章
-
c/c++ 多线程 等待一次性事件 std::promise用法
多线程 等待一次性事件 std::promise用法 背景:不是很明白,不知道为了解决什么业务场景,感觉std::async可以优雅的搞定一切的一次等待性事件,为什么还有个std::promise. ...
-
ES6语法 promise用法
ES6语法 promise用法 function doSomething(){ return new Promise((resolve,reject)=>{ resolve('jjjj');// ...
-
es6的promise用法详解
es6的promise用法详解 promise 原理 promise是es6的异步编程解决方案, 是es6封装好的对象: 一个promise有三种状态:Pending(进行中).Resolved(已完 ...
-
Es6 Promise 用法详解
Promise是什么?? 打印出来看看 console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...
-
ES6 Promise 用法讲解
Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...
-
Promise 用法
Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 Promise的构造函数接收一个参数,是 ...
-
ES6 Promise用法讲解
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. 下面代码创造了一个 ...
-
ES6 Promise 用法转载
Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方法,原型上有then.catch等同样很眼熟的方法. 那就new一个 var p = new Promise( ...
-
promise用法详解
es6的promise可谓是异步书写的一大福音,过去异步js书写是函数嵌套函数的方式,promise出现后书写异步js代码就变得美观得多了 以前的写法:回调函数不停嵌套 ajax('/banners' ...
随机推荐
-
局域网内Tomcat服务器没法访问
多半是防火墙的问题,在server2008上打开防火墙设置,关闭即可访问,不关闭的访问方式暂时好没研究出来
-
Java学习-集合(转)
在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...
-
C# yield return 流程理解
代码如下: 在Documents1方法中使用yield return之后, 下次在进入Documents1方法就是从上一次yield return部分执行 using System; using S ...
-
android的二进制和十六进制的相互转换工具类(一):
二进制和十六进制的相互转换工具类: package com.gzcivil.utils; public class BinStr { /** * 将二进制转换成16进制 * @param buf * ...
-
插件前奏-android黑科技 hook介绍
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52091833 Android hook相关学习 参考:http://www.cydia ...
-
js中字符替换函数String.replace()使用技巧
定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 语法 stringObject.replace(regexp/substr,replac ...
-
nfs的时间问题,影响编译
[root@okk dpdk]# rm -rf x86_64-native-linuxapp-gcc/ [root@okk dpdk]# A=`date +%s` ; B=`expr $A + `; ...
-
goto语句的升级版,setjmp,longjmp
我们知道goto语句是不能跳过函数的,但是在我么C语言的应用中,在不使用汇编的情况下,遇到需要跳出深层循环比如检错机制的时候,有确实想要跨函数跳转,有没有上面办法可以做到呢? 这就是今天要讲的两个库函 ...
-
[翻译] snapshotViewAfterScreenUpdates
snapshotViewAfterScreenUpdates This method very efficiently captures the current rendered appearance ...
-
AngularJs HTTP响应拦截器实现登陆、权限校验
$httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信.在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作.还有一些情况是,我们 ...