【译】FuseJS简介(中)

官网原文:https://www.fusetools.com/learn/fusejs#reactive-operators

反应式操作符 Reactive operators

FuseJS配备了整套从其它Observable生成新Observable的反应式操作符,这意味着如果原始的Observable发生了变化,则用反应式操作符生成的新的Observable也会发生变化。

注意!只有当最后生成的Observable是被使用的,比如数据绑定或是需要它的值,反应式操作才会计算出结果去生成这个Observable的值。举例说,如果你对一个Observable集合用了map(func)操作,然后想用console.log在终端显示出这个映射函数的结果,这些内容可能不会显示,这是因为作为结果的Observable没有做数据绑定,遇到这种情况,你可以为了debug去手动添加一个订户。

where(condition)

将条件为真的值返回成一个新的Observable

新的Observable时刻观察着旧的Observable, 当旧的值发生变化时,新的马上随之更新。

fruits = Observable(
    { name: 'Apple' , color: 'red'    },
    { name: 'Lemon' , color: 'yellow' },
    { name: 'Pear'  , color: 'green'  },
    { name: 'Banana', color: 'yellow' });

goodFruits = fruits.where(function(e){
    return e.color === 'yellow';
});

如果根据条件产生了一个Observablewhere操作符也会观察这这个条件。

map(func)

对一个Observable里的每个值都调用一遍参数函数,结果返回成一个新的Observable

var numbers = Observable(1, 4, 9);
var roots = numbers.map(function(number) {
    return Math.sqrt(number);
});

上例中,变量roots里值由numbers的数字求平方根组成,numbers里的值保持不变。

count()

从一个Observable得出其包含值的总数,然后存为另一个计数用的Observable。当原来的Observable新增或删除项时,计数的Observable数字也随之改变。

books = Observable("UX and you",
    "Observing the observer",
    "Documenting the documenter");
numBooks = books.count(); //result: 3
count(condition)

和上一条比,多了一个过滤条件,意思是只有条件为true的才计数。

not()

取反,将一个Observable的相反值返回成新的Observable, 比如一个Observable的值为true,则返回false, 反之亦然。

falseValue = Observable(false);
trueValue = falseValue.not();
filter(condition)

只有通过给定条件的才会返回为另一个变种的Observable,不然保持原有Observable的值。

这方法只用考虑Observalbe的首值或单独值。

expand(func)

将一个只包含一个数组的Observable拆散,把数组里的所有值作为单独项组合成另一个Observable

Observable([1,2,3]).expand() -> Observable(1,2,3)

订阅更新 Subscribing to updates

addSubscriber(func)

手动使一个Observable对变化做反应,只需要使用addSubscriber方法。这样当发生变化时,func就会运行。

removeSubscriber(func)

当对一个Observable值操作完成后,注意别忘了删除订阅(subscription),否则内存垃圾会越来越多。

username.removeSubscriber(usernameLogger);

其它

depend()
failed(message)
setValueExclusive(value, excludingObserver)

给一个Observable赋值而不通知excludingObserver

var observable = Observable(1);

var shouldGetNotification = function() { }
var shouldNotGetNotification = function() { }

observable.addSubscriber(shouldGetNotification);
observable.addSubscriber(shouldNotGetNotification);

observable.setValueExclusive(2, shouldNotGetNotification);
toString()

返回一个形容该Observable的字符串,包括其内容。

var testObservable = Observable(1, "two", "3");
testObservable.toString(); // "(observable) 1,two,3"

话题

Observable可以用来做很多事情:

  • 数据绑定Data Binding
  • 异步编程Asynchronous programming
  • 反应式编程Reactive programming

APIs 应用程序编程接口

Polyfills 兼容代码

FuseJS在所有支持平台上的运行环境为EcmaScript5.1。这里没有浏览器什么事儿,FuseJS只是提供了一个浏览器标准库的子集。为了让第三方库能工作,FuseJS用一些Polyfills兼容代码提供特色功能,典型的就是浏览器的功能。这些代码目前并不完备,所以有问题请到论坛发帖。

fetch

这是主要做HTTP request的方式。

下面是一个fetch的示例,首先用一个JavaScript对象转成JSON数据,POST到服务器端,然后服务器端返回JSON数据,再转成另一个JavaScript对象。

var status = 0;
var response_ok = false;

fetch('http://example.com', {
    method: 'POST',
    headers: { "Content-type": "application/json"},
    body: JSON.stringify(requestObject)
}).then(function(response) {
    status = response.status;  // Get the HTTP status code
    response_ok = response.ok; // Is response.status in the 200-range?
    return response.json();    // This returns a promise
}).then(function(responseObject) {
    // Do something with the result
}).catch(function(err) {
    // An error occured parsing Json
});
  • 完整的fetch的文档见于MDN

XMLHttpRequest

FuseJS支持XMLHttpRequest, 具体见MDN

Promise

对于Promise,FuseJS也有支持,具体见MDN

setTimeout

延时两秒再运行一个函数:

setTimeout(function() { alert("Alert"); }, 2000);

setTimeout做一个循环:

function poller() {
    // Do work (...)

    // And again in 1 second
    setTimeout(poller, 1000);
}
  • 关于setTimeout参见MDN

Storage

StorageAPI可以用来将文本保存为应用目录下的文件。

var storage = require('FuseJS/Storage');

write 写入

将字符串写入指定的文件。

storage.write(filename, value)
  • filename - 文件名
  • value - 需要写进文件的内容

返回的是一个含有布尔值的Promise, 可以告知内容写入文件成功与否。

storage.write("filename.txt", "filecontent");

read 读取

storage.read(filename)
  • filename - 要读取的文件

返回的是一个包含文件内容字符串的Promise

storage.read("filename.txt").then(function(content) {
    console.log(content);
}, function(error) {
    console.log(error);
});

保存文件的实际目录在不同的平台上也不尽相同。

writeSync 同步写

同步写入数据到应用文件夹, 如成功写入则返回true:

var wasWritten = storage.writeSync("filename.txt", "filecontent");

警告:此调用易堵塞,如果写入大量数据,请使用Storage.write

readSync 同步读

在应用的文件夹里同步读取文件内的数据:

var data = storage.readSync("filename.txt");

警告: 此调用易堵塞,如果读取大量数据,请使用Storage.read

deleteSync 同步删

从应用的文件夹里删除一个文件,成功后返回true

var data = storage.readSync("filename.txt");

Lifecycle 生命周期

用JavaScript响应Lifecycle的事件:

var lifecycle = require('FuseJS/Lifecycle');
lifecycle.onEnteringForeground = function() {
      initialize();
};

下列生命周期事件将被提升:

App的开始事件是隐式的,这就是当你的JS代码头一次被评估时。

  • onEnteringForeground - App脱离挂起状态,开始运行。App开始时可以得到该事件。
  • onEnteringBackground - App脱离运行状态,将被挂起。
  • onEnteringInteractive - App进入高度交互状态,开始接受事件。
  • onExitedInteractive - App部分被遮盖或不再是焦点状态(比如你拖出系统通知栏的时候)。
  • onTerminating - App将被关闭

Phone 电话

PhoneAPI用来初始化一个呼叫请求:

var phone = require('FuseJS/Phone');
phone.call("number");

Camera 摄像头

可以让你使用设备的摄像头拍照。

var camera = require('FuseJS/Camera');

示例:

camera.takePicture({ targetWidth: 640, targetHeight: 360}).then(function(file)
{
    // file is a standard JavaScript File object
    // file.path contains the path to the saved image on the device
}).catch(function(e) {
    console.log(e);
});

如果不想根据EXIF数据自动地旋转照片,你可以给原始请求加上一个correctOrientation值。

takePicture function

用设备的摄像头拍照;。

camera.takePicture({ targetWidth: width, targetHeight: height, correctOrientation: shouldCorrect })

选项对象包括下列属性:

  • targetWidth - 想要拍的照片宽度,单位为像素,如果省略,缺省值为上次的。
  • targetHeight - 想要拍的照片高度,单位为像素,如果省略,缺省值为上次的。
  • correctOrientation - 如果想要纠正照片的朝向,就设为true

该方法在拍照成功后返回一个Promise,最后生成一个file对象指向存储盘上的JPG图片。

提示:targetWidthtargetHeight只是建议值,最终拍摄的照片可能是任何尺寸。(WTF!)

Vibration

使用设备的震动功能。

var vibration = require('FuseJS/Vibration');

用例:

vibration.vibrate(0.8);

震动0.8秒。

InterApp

InterApp模块是专门为简化App之间通讯而设计的。

var interApp = require('FuseJS/InterApp');

目前它就处理两件事:

  • 用一个Uri请求启动另一个App
  • 接受另一个App的Uri启动请求

URI = Universal Resource Identifier 统一资源标识符

launchUri(uri)

用字符串参数调用该方法,Fuse就会请求系统打开目标App并处理Uri。

interApp.launchUri ('purple://some/uri')

onReceivedUri(uri)

这是一个回调函数,用来告知其它App正用一个Uri启动你的App。所以要接受这个通知,首先得给你的App定义一个Uri scheme, How?Fuse里很简单,只要在unoproj文件的Mobile字段加上一个UriScheme元素即可,如下所示:

"Mobile": {
  "UriScheme": "YourScheme",
  ...
},

就这样,每当设备上一个有着YourScheme字段的Uri被打开时,你的App就会被打开,并用完整的Uri调用onReceivedUri回调函数。

当上面的调用发生时,如果你的App已经打开了onReceivedUri,这时App会暂时脱离交互模式,别担心,这是完全正常的。

在你的JavaScript代码里使用该回调函数,如下所示:

var interApp = require('FuseJS/InterApp');

interApp.onReceivedUri = function(uri) {
    console.log ("js recieved Uri: " + uri);
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容