:Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该任务是否完成。

异步模式在Web编程中变得越来越重要,对于Web主流语言JavaScript来说,这种模式实现起来不是很利索,为此,许多JavaScript库(比如     jQuery和Dojo、AngularJS)添加了一种称为Promise的抽象(术语称作Deferred模式)。通过这些库,开发人员能够在实际编程中使用Promise模式,每个Promise都拥有一个叫做then的唯一接口,当Promise失败或成功时,它就会进行回调。它代表了一种可能会长时间运行而且不一定必须完成的操作结果。这种模式不会阻塞和等待长时间的操作完成,而是返回一个代表了承诺的(promised)结果的对象。

本文我们将讨论JavaScript库(比如jQueryAngularJS)是如何使用Promise模式的来处理异步的,其实就是通过回调的方式提供容错支持。

下面让我们来看看jQuery是如何操作的:

1
2
3
4
5
6
7
8
9
10
var $info = $("#info");
$.ajax({
    url:"/echo/json/",
    data: { json: JSON.stringify({"name": "someValue"}) },
    type:"POST",
    success: function(response)
    {
       $info.text(response.name);
    }
});

在这个例子中,你可以看到当设置成功后会指定一个回调,这并不是Promise,但却是一种很好的回调方式。当Ajax调用完成后,它便会执行success函数。根据库所使用的异步操作,你可以使用各种不同的回调(即任务是否成功,都会进行回调,做出响应)。使用Promise模式会简化这个过程,异步操作只需返回一个对象调用。这个Promise允许你调用一个叫做then的方法,然后让你指定回调的function(s)个数,下面让我们来看看jQuery是如何建立Promise的:

1
2
3
4
5
6
7
8
9
10
11
12
13
var $info = $("#info");
$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
});

有趣的是,ajax对象返回xhr对象实现Promise模式,所以我们可以调用then方法,这样做的优势是你可以链式调用,实现独立操作,如下所示 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var $info = $("#info");
$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
})
.then(function () {
    $info.append("...More");
})
.done(function () {
    $info.append("...finally!");
});

由于许多库都开始采用Promise模式,所以异步操作会变的非常容易。但如果站在相反的角度思考,Promise将会是什么样子的呢?其中一个非常重要的模式是函数可以接受两种功能,一个是成功时的回调,另一个是失败时的回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var $info = $("#info");
$.ajax({
    // Change URL to see error happen
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    // success
    $info.text(response.name);
},
function () {
    // failure
    $info.text("bad things happen to good developers");
})
.always(function () {
    $info.append("...finally");
});

需要注意的是,在jQuery里,无论成功还是失败,我们都会使用一个调用来指定我们想要调用的。下面让来看看AngularJS是如何使用Promise模式的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var m = angular.module("myApp", []);
m.factory("dataService", function ($q) {
    function _callMe() {
        var d = $q.defer();
        setTimeout(function () {
            d.resolve();
            //defer.reject();
        }, 100);
        return d.promise;
    }
    return {
        callMe: _callMe
    };
});
function myCtrl($scope, dataService) {
    $scope.name = "None";
    $scope.isBusy = true;
    dataService.callMe()
      .then(function () {
        // Successful
        $scope.name = "success";
      },
      function () {
        // failure
        $scope.name = "failure";
      })
      .then(function () {
        // Like a Finally Clause
        $scope.isBusy = false;
      });
}

你可以在JSFiddle里试试这些例子,并且看看会产生哪些效果。使用Promise来操作异步是一种非常简单的方式,而且还可以简化你的代码,岂不是一举两得的好方法。

更多关于Promise的介绍及示例,可以前往官网查看

JavaScript异步编程助手:Promise模式的更多相关文章

  1. JavaScript异步编程的Promise模式(转)

    异步模式在web编程中变得越来越重要,对于web主流语言Javascript来说,这种模式实现起来不是很利索,为此,许多Javascript库(比如 jQuery和Dojo)添加了一种称为promis ...

  2. JavaScript异步编程的Promise模式

    参考: http://www.infoq.com/cn/news/2011/09/js-promise http://www.cnblogs.com/rubylouvre/p/3495286.html ...

  3. javascript异步编程,promise概念

    javascript 异步编程 概述 采用单线程模式工作的原因: 避免多线dom操作同步问题,javascript的执行环境中负责执行代码的线程只有一个 内容概要 同步模式和异步模式 事件循环和消息队 ...

  4. [转载]JavaScript异步编程助手:Promise模式

    http://www.csdn.net/article/2013-08-12/2816527-JavaScript-Promise http://www.cnblogs.com/hustskyking ...

  5. Javascript异步编程之三Promise: 像堆积木一样组织你的异步流程

    这篇有点长,不过干货挺多,既分析promise的原理,也包含一些最佳实践,亮点在最后:) 还记得上一节讲回调函数的时候,第一件事就提到了异步函数不能用return返回值,其原因就是在return语句执 ...

  6. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  7. javascript异步编程的前世今生,从onclick到await/async

    javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...

  8. Promises与Javascript异步编程

    Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...

  9. 5分种让你了解javascript异步编程的前世今生,从onclick到await/async

      javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...

随机推荐

  1. VS2013启动 外接程序VMDebugger未能加载或导致了异常

    故障现象:打开Visual Studio 2010后弹出错误框,外接程序VMDebugger未能加载或导致了异常,是否希望移除该外接程序,错误号:80004005.系统版本:WIN10 64位专业版, ...

  2. 关于golang的label

    1 label所在的代码段在没有跳转的时候按照所在的位置按顺序执行 2 break label和continue label可以一次性从多重循环中跳出 3 goto label的用法和c/c++中的一 ...

  3. C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)(转)

    C#打印条码BarTender SDK打印之路和离开之路(web平凡之路) 从来没想过自己会写一篇博客,鉴于这次从未知的探索到一个个难点的攻破再到顺利打印,很想记录这些点滴,让后人少走弯路. 下面走进 ...

  4. IDEA在resources下创建多级目录

    在resource下,创建多级目录,应在每个目录之间用"/"隔开,这样就不需要再手动一层层目录的分别添加了!

  5. 【WPS/Visio】WPS word无法复制或编辑Visio对象

    前言 Win10,WPS2019,Visio2016. 好像是有一次设置 .vsdx 的默认打开方式为Visio,之后每次在WPS里复制Visio对象,或双击编辑WPS word中以前的Visio对象 ...

  6. markdown编辑器学习

    markdown是一块文本编辑器,属于纯文本文件,可以使用任何编辑器打开.对于写作来说是一个好帮手,它的好处有很多,比如可以直接转成html,制作电子书等.今天开始学习一下这个神奇的编辑器.从今天起把 ...

  7. JS 的 Browser对象

    Window对象 closed innerHeight    窗口文档显示区的高度,包括滚动条 outerHeight    窗口总高度,包括工具条和滚动条 open() close() alert( ...

  8. 基于maven的javaweb项目模块化开发

    转自:https://my.oschina.net/kingfire/blog/273381 基于maven的javaweb项目模块化开发 引言 考虑团队拥有多个类似项目的情况,比如一些功能差异不大的 ...

  9. Java的volatile

    1.同步 同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级 如图,如果变量没有volatile关键字,那么A线程对该变量的改变存储在内存A,B变量不 ...

  10. python之路之——操作系统的发展历史

    阅读目录 手工操作 —— 穿孔卡片 批处理 —— 磁带存储和批处理系统 多道程序系统 分时系统 实时系统 通用操作系统 操作系统的进一步发展 操作系统的作用 手工操作 —— 穿孔卡片 1946年第一台 ...