【译】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);
};

你可能感兴趣的:(【译】FuseJS简介(中))