Douglas Crockford 大神写的 JavaScript 异步控制库:RQ(下)

RQ 库 The RQ Library

RQ 仅仅是一个文件,rq.js。运行起来创建一个 RQ 变量,该变量包含四个函数。

RQ is delivered as a single file, rq.js. When run, it produces an RQ variable containing an object containing four functions.

RQ.sequence(requestors)
RQ.sequence(requestors, milliseconds)

RQ.sequence 有一个请求者函数所构成的数组的参数,还有一个可选的参数,用于表示超时的。返回值是另一个总的请求者,它能够依次执行里面的每一个请求者,把上一个结果按照顺序地交给下一个。如果全体完成,那么最后一个请求者的结果将是全体的结果,以数组形式出现。如果数组中的一个请求者失败了,那么表示这个串行队列失败。数组并没有改变。

RQ.sequence takes an array of requestor functions and an optional time limit in milliseconds. It returns a requestor function that will start each of the requestors in order, giving the result of each to the next one. If all complete successfully, the result will be the result of the last requestor in the array. If any of the requestors in the array fail, then the sequence fails. The array is not modified.

如果传入毫秒数的参数,则表示是超时的参数。

If a milliseconds argument is provided, then the sequence will fail if it does not finish before the time limit.

RQ.parallel(requireds)
RQ.parallel(requireds, milliseconds)
RQ.parallel(requireds, optionals)
RQ.parallel(requireds, milliseconds, optionals)
RQ.parallel(requireds, optionals, untilliseconds)
RQ.parallel(requireds, milliseconds, optionals, untilliseconds)

RQ.parallel 有一个必要请求者参数,为请求者函数所构成数组,及其用于表示超时的毫秒数参数(可选的),另外还有一个可选请求者参数(也是数组),及其用于表示超时的毫秒数参数(可选的)。该函数会返回另外一个总的请求者,会立刻执行必要请求者和可选请求者。结果为所有请求者的结果。如果有两个数组传入,结果数组的长度是那个传入数组总数之和。第一个请求者的结果就是结果数组中的第一个元素。整个并行任务完成与否取决于那些必要请求者,必要请求者成功了则成功。可选请求者的成功与否不会影响整个请求任务。这可用于最佳的尝试,从而获得了可以达成的结果。数组并没有改变。

RQ.parallel takes an array of required requestor functions, and an optional time limit in milliseconds, and an optional array of optional requestors and an optional guaranteed time for the optional requestors. It returns a requestor function that will start all of the required and optional requestors at once. The result is an array containing all of the results from all of the requestors. If both arrays were provided, the length of the results array is the sum of the lengths of the two arrays. The result of the first requestor will be in the first position of the results array. The parallel will succeed only if all of the required requestors succeed. The array of optional requestors contains requests that can fail without causing the entire parallel operation to fail. It can be used as a best effort, obtaining the results that are attainable. The arrays are not modified.

如果提供了毫秒数的参数,那么表示在时限到来之前还没有完成请求的话,将宣告并行工作失败。缺省情况下(没有提供 untilliseconds),不管可选请求者怎么样,必要请求者完毕了可选请求者就完毕。如果提供了 untilliseconds 参数,就按照这个时限来对可选请求者限制。如果没有提供必要请求者,那么应该至少要传入一个可选请求者,并且在规定时限完成的话,这个并行就成功了。

If a milliseconds argument is provided, then the parallel will fail if all of the required requestors do not finish before the time limit. By default, the optionals have until all of the required requestors finish. The untilliseconds argument guarantees the optionals some amount of time. untilliseconds may not be larger than milliseconds. If the requireds array is empty, and if at least one optional requestor is successful within the allotted time, then the parallel succeeds.

RQ.parallel 并没有对 JavaScript 语言层面添加并行机制。它能让 JavaScript 程序充分利用语言层面原生的并行机制。程序自己并不是一脚包办所有事情,而且发出请求来让其他的进程或者机器来搞定事情,这些进程或者机器都是独立执行的。

RQ.parallel does not add parallelism to JavaScript. It allows JavaScript programs to effectively exploit the inherent parallelism of the universe. It is likely that many of the requestors will be communicating with other processes and other machines. Those other processes and machines will be executing independently.

RQ.race(requestors)
RQ.race(requestors, milliseconds)

RQ.race 有一个请求者函数所构成的数组的参数,还有一个可选的参数,用于表示超时的。返回值是另一个总的请求者,它能够马上执行所有的请求者,但最终结果取得是最先成功的那次结果。如果数组中所有的请求者失败了,那么表示这个竞争失败。数组并没有改变。

如果传入毫秒数的参数,则表示是超时的参数。

If a milliseconds argument is provided, then the race will fail if it does not finish before the time limit.

RQ.fallback(requestors)
RQ.fallback(requestors, milliseconds)

RQ.fallback 有一个请求者函数所构成的数组的参数,还有一个可选的参数,用于表示超时的。返回值是另一个总的请求者,虽然它也会如串行般依次执行,但只要有一个请求者执行成功了,那么剩余的请求者将不会执行。如果数组中所有的请求者失败了,那么表示这个串行队列失败。数组并没有改变。

RQ.fallback takes an array of requestor functions and an optional time limit in milliseconds. It returns a requestor function that will try each of the requestors in order until one is successful. If all of the requestors in the array fail, then the sequence fails. The array is not modified.

如果传入毫秒数的参数,则表示是超时的参数。

If a milliseconds argument is provided, then the fallback will fail if it does not finish before the time limit.

函数类型 Function Types

RQ 使用了四种类型的参数:requestors,callbacks,cancels和 factories。

RQ makes use of four types of functions: requestors, callbacks, cancels, and factories.

请求者 Requestor(callback, value)

请求者函数本身为函数类型,可表示某种任务。它可以是一个普通的函数,也可以是复杂的工作、任务或者操作,总之这些都是需要一定时间才能完成的工作,甚至也可以在多台机器上完成的。请求者函数有个两个参数,一个是回调函数,另外一个是可选值。请求者会对回调函数传入其结果并执行。可选值能够使之前的值按照顺序送入到请求者之中。

A requestor is a function that represents some unit of work. It can be a simple function, or it can be a complex job, task, production step, or operation that will organize the work of many machines over a long period of time. A requestor function takes two arguments: A callback and an optional value. The callback will be used by the requestor to communicate its result. The optional value makes the result of a previous value in a sequence to the requestor.

为了可以取消请求,请求者可以选择返回取消函数来取消请求。

A requestor may optionally return a cancel function that can be used to cancel the request.

回调函数 Callback(success, failure)

回调函数就是送人到请求者的那个回调函数,可把请求者的值传入这个回调函数。回调函数有两个参数:成功或失败。若 failure 无意义,则代表请求者的请求成功了。

A callback is a function that is passed to a requestor so that the requestor can communicate its result. A callback can take two arguments, success and failure. If failure is falsy, then the requestor was successful.

当直接调用某个请求者时,你只需要传入一个回调函数,例如为了启动多个步骤的工作需要调用 RQ.sequence 的结果。这工作的结果将是传入到回调函数中的第一个参数。

You only have to provide a callback when calling a requestor directly, such as calling the result of RQ.sequence to start a multistep job. The result of the job will be the first argument passed to your callback function.

取消函数 Cancel(reason)

取消函数是指会尝试停止请求者执行的函数。取消函数可以使流程中不再需要的任务停止。例如 RQ.race 启动了多个请求者,若其中一个请求者获得了成功,那么其余的请求者则不再需要执行,会被全部取消执行。取消函数既不能代表回滚(rollback),也不能代表后退(undo)。

A cancel is a function that will attempt to stop the execution of a requestor. A cancel function makes it possible to stop the processing of a job that is no longer needed. For example, if several requestors are started by RQ.race and if one of the requestors produces an successful result, the results of the other requestors may be cancelled. Cancellation is intended to stop unnecessary work. Cancellation does not do rollbacks or undo.

取消函数可以由请求者返回。如果请求者对另外一个请求中的进程发出信息,那么取消函数应该要对同样那个进程发出消息,以告知那个进程不需要再工作了。

A cancel function may optionally be returned by a requestor. If a requestor sends a message to another process requesting work, the cancel function should send a message to the same process indicating that the work is no longer needed.

工厂函数 Factory( . . . )

工厂函数就是生产请求者的函数。请求者的制定过程就是在工厂函数中利用那个参数完成的。RQ 提供的四个函数(RQ.sequenceRQ.parallelRQ.raceRQ.fallback)皆是工厂函数。工厂函数能够简化程序开发。

A factory is a function that makes requestor functions. A factory will usually take arguments that allow for the customization of a requestor. The four functions provided by RQ (RQ.sequence, RQ.parallel, RQ.race, RQ.fallback) are all factory functions. Factory functions can simplify application development.

超时 Timeouts

有时候虽然能返回正确的结果,但如果太久的话那么也相当于是失败了。RQ 提供了一个可选的超时值来限制 requestor 进行的请求时间。如果请求者花太多时间来工作了,那么就应该要自动取消之。RQ.fallback 使得失败有所恢复。

Sometimes a correct result that takes too long is indistinguishable from a failure. RQ provides optional timeout values that limit the amount of time that a requestor is allowed to take. If a requestor takes too long to do its work, it can be automatically cancelled. RQ.fallback makes such failures recoverable.

例子 Samples

特性请求者 Identity Requestor

identity_requestor 函数接收一个值并将其送到所传入的回调函数中。如果把 identity_requestor 放置于串行队列中,则仅仅是把前一个请求的结果交给下一个请求者。

The identity_requestor receives a value and delivers that value to its callback. If the identity requestor is placed in a sequence, it acts as a nop, sending the result of the previous requestor to the next requestor.

function identity_requestor(callback, value) {
    return callback(value);
}

全称请求者 Fullname Requestor

全称请求者 fullname_requestor 接收一个对象,读取其身上的字符串属性,然后组成全称,最后将全称送到回调。

The fullname_requestor receives an object and delivers a string made from properties of the object.

function fullname_requestor(callback, value) {
    return callback(value.firstname + ' ' + value.lastname);
}

请求化工厂 Requestorize Factory

请求化工厂 requestorize 可以返回一个请求者函数。这里就是预先确定对回调函数参数的处理(译注:对要传入到 callback 的参数进行处理,处理过程在 func 中,在执行工厂函数时确定)。

The requestorize factory can make a requestor from any function that takes a single argument.

function requestorize(func) {
    return function requestor(callback, value) {
        return callback(func(value));
    };
}

我们可以利用该工厂函数生成序列中多个处理流程。例如,我们有下面这个函数,是根据一个对象来返回全称的:

We can use this to make processing steps in a sequence. For example, if we have a function that takes an object and returns a fullname:

function make_fullname(value) {
    return value.firstname + ' ' + value.lastname;
}

那么我们接着可以将其转变为请求者,就像 fullname_requestor:

We can turn it into a requestor that works just like the fullname_requestor:

var fullname_requestor = requestorize(make_fullname);

延时请求者 Delay Requestor

请求者 delay_requestor 插入一个延时到串行中,非阻塞。

The delay_requestor inserts a delay into a sequence without blocking.

function delay_requestor(callback, value) {
    var timeout_id = setTimeout(function () {
    	return callback(value);
    }, 1000);
    return function cancel(reason) {
        return clearTimeout(timeout_id);
    };
}

真实请求者中,不是调用 setTimeout, 而是一个消息将被发送到一个进程;而不是调用 clearTimeout,而是一个消息将被发送到相同的进程以取消的工作。

In a real requestor, instead of calling setTimeout, a message will be transmitted to a process, and instead of calling clearTimeout, a message will be transmitted to the same process to cancel the work.

延时工厂 Delay Factory

延时工厂就是返回延时请求者之用。

The delay factory simplifies the making of delay requestors.

function delay(milliseconds) {
    return function requestor(callback, value) {
        var timeout_id = setTimeout(function () {
    	    return callback(value);
        }, milliseconds);
        return function cancel(reason) {
            return clearTimeout(timeout_id);
        };
    };
}

构造工厂 Construct Factory

构造工厂 construct 返回一个请求者,其参数是并行操作构成的数组另外,由于串行操作中需要对象结构的数据,所以亦安排了构造工作转换这个对象。

The construct factory makes a requestor that takes an array of results from a parallel operation and converts it into an object for use by subsequent operations in a sequence.

function construct(array) {
    return function requestor(callback, value) {
        var object = Object.create(null);
        array.forEach(function (name, index) {
            object[name] = value[index];
        });
        return callback(object);
    };
}

虽然 buildPage 请求者采用了数组的结构,但我们可以使用对象格式的结构,这样的话,代码阅读起来会更能够自我描述(译注:更好读)。通过构造工厂 construct 实现更简单。

We could write our buildPage requestor to take an array of values, but it makes more sense to give it an object so that its code will be self documenting. The construct factory makes that easy.

respond = RQ.fallback([
    RQ.sequence([
        getId,
        getPreference,
        RQ.parallel([
            getNav,
            RQ.race([
                getAd(adnet.klikHaus),
                getAd(adnet.inUFace),
                getAd(adnet.trackPipe)
            ]),
            RQ.fallback([
                fetch("weather", localCache),
                fetch("weather", localDB),
                fetch("weather", remoteDB)
            ]),
            getMessageOfTheDay
        ], [
            getHoroscope,
            getGossip
        ], 50),
        construct(['nav', 'ads', 'weather', 'message', 'horoscope', 'gossip']),
        buildPage
    ], 100),
    planB
]};

执行 respond 发起请求,然后传入的回调函数将会接受最终值,getId 会最先得到值。

To start things running, call respond, passing a callback function that will receive the final result, and the intial value that wll be given to getId.

时间: 2024-10-14 23:25:35

Douglas Crockford 大神写的 JavaScript 异步控制库:RQ(下)的相关文章

Douglas Crockford 大神写的 JavaScript 异步控制库:RQ(上)

RQ Douglas Crockford 2015-10-06 翻译 http://blog.csdn.net/zhangxin09 RQ 是一个运行在服务端用于管理异步的小型 JavaScript 库. RQ is a small JavaScript library for managing asynchronicity in server applications. 源码在 https://github.com/douglascrockford/RQ.本页在 http://www.RQ.c

请看一个大神写的lambda表达式,不用linq请问怎么调用

问题描述 请看一个大神写的lambda表达式,不用linq请问怎么调用 Func<int, bool> MyAnd(Func<int, bool> f1, Func<int, bool> f2) { return x => f1(x) && f2(x); } 解决方案 直接调用也可以: bool b1 = MyAnd(x => x < 10, x => x % 2 == 0)(4); bool b2 = MyAnd(x =>

c++基础c++-求大神写一段c++代码,做题能做对但是自己写代码就漏洞百出,求大神指导

问题描述 求大神写一段c++代码,做题能做对但是自己写代码就漏洞百出,求大神指导 年龄 Age姓名 char name公有成员函数: 构造函数 带参数的构造函数Student(int mchar); 不带参数的构造函数 Student() 析构函数 -Student() 改变数据成员值函数 void SetMemer(int mchar *) 获取数据成员函数 int GetAge() char * GetName()要求:在main()中定义一个有3个元素的对象数组并分别初始化,然后输出对象数

应用-麻烦大神写出一个c++程序出来

问题描述 麻烦大神写出一个c++程序出来 几何图形的简单计算.内容是用C++设计一个业务处理系统,其业务就是进行简单的几何计算:l输入圆的半径,计算并输出圆的周长和面积:l输入圆柱的半径和高,计算并输出圆柱的表面积和体积:l输入圆锥的半径和高,计算并输出圆锥的表面积和体积:l输入圆球的半径,计算并输出圆球的表面积和体积:l输入长方形的长和宽,计算并输出长方形的周长和面积:l输入长方体的长.宽和高,计算并输出长方体的表面积和体积.要求:①必须设计圆.圆柱.圆锥.圆球.长方形.长方体等类:②必须应用

求大神解答-求大神写一下这个SQL语句,紧急

问题描述 求大神写一下这个SQL语句,紧急 表acct_item(acct_item_id,acct_id,acct_item_type_id,charge(费用:单位分)).查询acct_id总费用大于100元的合同号,按总费用降序,总费用相同时,按acct_id升序排列 解决方案 select acct_id from acct_item where charge>'10000' order by charge desc,acct_id desc 解决方案二: select acct_id

求大神写个读取SQLserver数据库显示柱状图的代码,跪求

问题描述 求大神写个读取SQLserver数据库显示柱状图的代码,跪求 解决方案 解决方案二:你sql读取信息,然后在柱状图上绑定对应的字段就可以了.解决方案三:.NET3.5以上的vs项目,可以使用Chart控件,工具箱--->数据,然后在属性里指定DataSourceID,根据向导完成即可,中间要建立DataSource,指定表,字段等解决方案四:Sql只是提供数据,至于显示数据的方式,都是展示层的控件来决定的.就像楼上说的chart控件或者网上许多的第三方控件解决方案五:HChartECh

php-怎样删除二维数组中相同的一位数组 并保持相同键名 求大神写个函数

问题描述 怎样删除二维数组中相同的一位数组 并保持相同键名 求大神写个函数 Array ( [0] => Array ( [year] => 2013-2014 [term] => 1 [course_code] => 00008069 [course_name] => 咖啡世界 [course_nature] => 任意选修 [course_attribution] => 人文素养类 [credit] => 2.0 [point] => 4.1 [g

jsp-下边的代码谁懂啊,大神求解释。顺道告诉我下想学关于这个看什么,谢谢啦

问题描述 下边的代码谁懂啊,大神求解释.顺道告诉我下想学关于这个看什么,谢谢啦 <head> <jsp:include page='/res/inc/inc.jsp' flush='true'/> <style> .FixedTitleRow { position: relative; top: expression( this.offsetParent.scrollTop ); z-index: 10; background-color: #ffffff; } .Fi

sharepoint 2013-求问各位大神在SharePoint 2013中 获取list下所有column的名字和值得方法

问题描述 求问各位大神在SharePoint 2013中 获取list下所有column的名字和值得方法 现在在SharePoint开发遇到难题,想要获取某个list中的所有column的名字和对应的值得种类.本来想的只要找到column的头上下拉列表中对应的字段,就可以全找到了,但这个实在找不到.求问获取column的name和value的方法,多谢各位大神解救啊 解决方案 首先连接sharePoint找到每一列的属性,在属性里有你想要的name和类型. 在VS的右上角有连接sharePoin