背景

见上一篇。 面向对象的链式调用中,掺杂了 一个一部动作, 对于这种工作链, 是非同步执行的链。

LazyMan("Hank").sleep(1).eat("dinner")

同步执行的工作链中, 任何一个动作,即函数调用, 都是同步的, 可理解为普通的函数。

异步的工作链, 前提条件是工作链中,存在至少一个  动作是 异步的。 例如 sleep

Promise

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

The Promise object is used for asynchronous computations. A Promise represents a value which may be available now, or in the future, or never.

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise for the value at some point in the future.

A Promise is in one of these states:

  • pending: initial state, not fulfilled or rejected.
  • fulfilled: meaning that the operation completed successfully.
  • rejected: meaning that the operation failed.

A pending promise can either be fulfilled with a value, or rejected with a reason (error). When either of these happens, the associated handlers queued up by a promise's then method are called.

四大特性:

Promise.all(iterable)  --- 我有一个愿望, 等待所有的我指定的愿望 Promise都实现, 我的才能实现。

Promise.race(iterable) --- 我有一个愿望,等待我所指定的愿望中,只要有一个实现, 我的愿望就实现。

Promise.reject(reason) --- 我有一个愿望, 注定不会实现。

Promise.resolve(value) --- 我有一个愿望, 注定要实现。

then特性:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

The then() method returns a Promise. It takes up to two arguments: callback functions for the success and failure cases of the Promise.

Syntax

p.then(onFulfilled[, onRejected]);

p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});

Parameters

then returns a Promise which is determined by the input functions:

  • If onFulfilled or onRejected throws an error, or returns a Promise which rejects, then returns a rejected Promise.
  • If onFulfilled or onRejected returns a Promise which resolves, or returns any other value, then returns a resolved Promise.

Chaining

The then method returns a Promise which allows for method chaining.

You can pass a lambda to then and if it returns a promise, an equivalent Promise will be exposed to the subsequent then in the method chain. The below snippet simulates asynchronous code with the setTimout function.

If onFulfilled returns a promise, the return value of then will be resolved/rejected by the promise.

function resolveLater(resolve, reject) {
setTimeout(function () {
resolve(10);
}, 1000);
}
function rejectLater(resolve, reject) {
setTimeout(function () {
reject(20);
}, 1000);
} var p1 = Promise.resolve("foo");
var p2 = p1.then(function() {
// Return promise here, that will be resolved to 10 after 1 second
return new Promise(resolveLater);
});
p2.then(function(v) {
console.log("resolved", v); // "resolved", 10
}, function(e) {
// not called
console.log("rejected", e);
}); var p3 = p1.then(function() {
// Return promise here, that will be rejected with 20 after 1 second
return new Promise(rejectLater);
});
p3.then(function(v) {
// not called
console.log("resolved", v);
}, function(e) {
console.log("rejected", e); // "rejected", 20
});

解法

结合 then的链使用, 给出方案:

function _LazyMan(name) {

    this.promiseGetters = [];

    var makePromise = function  () {
var promiseObj = new Promise(function(resolve, reject){
console.log("Hi! This is " + name + "!"); resolve();
}) return promiseObj;
} this.promiseGetters.push(makePromise); // 在各个Promise的then函数中,将任务序列穿起来
var self = this;
var sequence = Promise.resolve();
// Promise.resolve 等价于
// var sequence = new Promise(function (resolve, reject) {
// resolve();
// })
setTimeout(function(){
for (var i = 0; i < self.promiseGetters.length; i++) {
var nowPromiseGetter = self.promiseGetters[i];
var thenFunc = (function (nowPromiseGetter) {
return function () {
return nowPromiseGetter()
}
})(nowPromiseGetter); sequence = sequence.then(thenFunc);
}; }, 0); // 在下一个事件循环启动任务
} _LazyMan.prototype.eat = function(name) {
var makePromise = function () {
var promiseObj = new Promise(function(resolve, reject){
console.log("Eat " + name + "~"); resolve();
}) return promiseObj;
} this.promiseGetters.push(makePromise); return this; // 实现链式调用
} _LazyMan.prototype.sleep = function(time) {
var makePromise = function () {
var promiseObj = new Promise(function(resolve, reject){ setTimeout(function(){ console.log("Wake up after " + time + "s!"); resolve(); }, time * 1000);
}) return promiseObj;
} this.promiseGetters.push(makePromise); return this;
} /* 封装 */ function LazyMan(name){ return new _LazyMan(name); } LazyMan("Hank").sleep(1).eat("dinner")

LazyMan的Promise解法的更多相关文章

  1. 由LazyMan联想到的

    LazyMan问题与解法 http://mp.weixin.qq.com/s/drNGvLZddQztcUzSh8OsSw 给出了一道题目,并给出了解法: 题目: 实现一个LazyMan,可以按照以下 ...

  2. 转评:你造promise就是monad吗

    看到一遍好文章,与我的想法如出一辙,先转为敬.首先说说我对Monad和promise的理解: Monad的这种抽象方式是为了简化程序中不确定状态的判断而提出的,能够让程序员从更高的层次顺序描述程序逻辑 ...

  3. 面试题-lazyMan实现

    原文:如何实现一个LazyMan 面试题目 实现一个LazyMan,可以按照以下方式调用: LazyMan('Hank'),输出: Hi, This is Hank! LazyMan('Hank'). ...

  4. 面试题 LazyMan 的Rxjs实现方式

    前言 笔者昨天在做某公司的线上笔试题的时候遇到了最后一道关于如何实现LazyMan的试题,题目如下 实现一个LazyMan,可以按照以下方式调用:LazyMan("Hank")输出 ...

  5. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  6. alias导致virtualenv异常的分析和解法

    title: alias导致virtualenv异常的分析和解法 toc: true comments: true date: 2016-06-27 23:40:56 tags: [OS X, ZSH ...

  7. Javascript - Promise学习笔记

    最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下.   一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...

  8. 路由的Resolve机制(需要了解promise)

    angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...

  9. Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法

    本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...

随机推荐

  1. 11.ok6410之led驱动程序编写

    led驱动程序编写 本文主要包含三部分,led驱动程序led.c编写,编译驱动程序的makefile的编写,以及使用驱动程序的应用程序led_app的编写 一.led.c编写 #include < ...

  2. Hibernate的抓取策略

    立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...

  3. html学习第二天—— 第八章—— CSS选择器

    标签选择器其实就是html代码中的标签.如右侧代码编辑器中的<html>.<body>.<h1>.<p>.<img>.例如下面代码:p{fo ...

  4. 全站 HTTPS 来了

    !版权声明:本文为腾讯Bugly原创文章,转载请注明出处腾讯Bugly特约作者:刘强 最近大家在使用百度.谷歌或淘宝的时候,是不是注意浏览器左上角已经全部出现了一把绿色锁,这把锁表明该网站已经使用了 ...

  5. Nginx二级域名及多Server反向代理配置

    Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了. 注:nginx反向代理同一ip多个域名,给head ...

  6. js 类型转换学习

    类型转换分为显示转换和隐式转换 参考http://www.cnblogs.com/mizzle/archive/2011/08/12/2135885.html 先事件显示的 通过手动进行类型转换,Ja ...

  7. Eclipse 报java.lang.OutOfMemoryError: PermGen space错

    这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage C ...

  8. Memcached: List all keys

    In the general case, there is no way to list all the keys that a memcached instance is storing. You ...

  9. javascript:cors跨域postMessage、xhr2和xmldomain

    一.h5 postMessage node http-server配置服务器 有关配置:请参考我的http://www.cnblogs.com/leee/p/5502727.html 我把文件夹a配置 ...

  10. jenkins使用git SCM时changelog乱码(Jenkins部署在Linux上,任务在Windows Slave上构建)

    问题原因 changelog的获取方式(git-client插件): 首先调用git whatchanged命令,读取输出字节流(UTF-8编码的Commit Message). 将字节流解码为字符串 ...