zoukankan      html  css  js  c++  java
  • [JavaScript]Promise:异步编程

    1 文由

    某项目的需求:先要请求API1,再以API1的结果请求API2.

    var n, a;
    //var r = window.md5;
    var r =  function (password, username) {
    	return new Promise((resolve, reject) => {	
    		// 校验 获得 salt
    		var saltUrl = "/wydaas/gateUser/noCheck/inner-user/salt.json"; // http://xx.yy.zz.kk:8080/wydaas/gateUser/noCheck/inner-user/salt.json
    		var postData = { userName: username };
    		//saltUrl += "?userName="+username;
    		//var postData = null;
    		console.log(postData);
    		t.$http.post(saltUrl, postData).then((function(e) {
    			var n = e.data.data;
    			console.log("e:");
    			console.log(e);
    			var salt = e.body.data.data; // response 的 js json 对象
    			var text = password+"{"+salt+"}";
    			console.log(text);
    			console.log(sha256_digest(text));
    			resolve(sha256_digest(text));
    			/*
    			var n = e.data.data;
    			n.status ? (t.$message({
    				type: "success",
    				message: n.message || t.i18n.message.OPERATION_COMPLETE
    			}),
    			t.loginData.show = !1,
    			t.setCookieFun(),
    			t.$router.replace({
    				path: "/catalog"
    			}),
    			window.location.reload()) : (t.$alert(n.message || t.i18n.message.OPERATION_ERROR, t.i18n.message.SYSTEM_TXT, {
    				closeOnClickModal: !1,
    				confirmButtonText: t.i18n.message.OK,
    				type: "error"
    			}),
    			t.delCookie("accountInfo")),
    			t.saveLoading = !1 */
    		}
    		)).catch((function(e) {
    			this.saveLoading = !1;
    			reject(e);
    		}
    		))
    	})
    };
    
    
    "0" === t.loginType && (
    	r(t.formData.userPassword, t.formData.userName).then(res => {
    		console.log("res:" + res);
    		n = "/wydaas/gateUser/noCheck/loginInner.json",
    		a = {
    			userName: t.formData.userName,
    			//pwd: r(t.formData.userPassword, t.formData.userName)
    			pwd: res
    		},
    		
    		console.log("a:"),
    		console.log(a),
    		
    		t.$http.post(n, a).then((function(e) {
    			var n = e.data.data;
    			n.status ? (t.$message({
    				type: "success",
    				message: n.message || t.i18n.message.OPERATION_COMPLETE
    			}),
    			t.loginData.show = !1,
    			t.setCookieFun(),
    			t.$router.replace({
    				path: "/catalog"
    			}),
    			window.location.reload()) : (t.$alert(n.message || t.i18n.message.OPERATION_ERROR, t.i18n.message.SYSTEM_TXT, {
    				closeOnClickModal: !1,
    				confirmButtonText: t.i18n.message.OK,
    				type: "error"
    			}),
    			t.delCookie("accountInfo")),
    			t.saveLoading = !1
    		}
    		)).catch((function() {
    			this.saveLoading = !1
    		}
    		))
    		
    	})
    )
    

    2 Promise 简介

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大。
    它最早由社区提出并实现,ES6将其写进了语言标准,统一了用法,并原生提供了Promise对象。

    特点

    • promise是一个对象

    JS中,对象函数的区别就是对象可以保存状态,函数不可以(闭包除外)

    • 摆脱层层链式callback;代码易于理解和维护。并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据

    • 多个异步等待合并便于解决

    • 【状态变更的响应处理:then】当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;

    • 【状态变更的不可变更性】但promise状态一经改变,不会再变。

    3 Promise 详解

    样例/格式

    new Promise(
      function (resolve, reject) {
        // 一段耗时的异步操作
        resolve('成功') // 数据处理完成
        // reject('失败') // 数据处理出错
      }
    ).then(
      (res) => {console.log(res)},  // 成功
      (err) => {console.log(err)} // 失败
    )
    
    var funcA = function (a, b) {
    	return new Promise(function (resolve, reject) {
    		// 一段耗时的异步操作
    		console.log(a, b);
    		resolve('成功') // 数据处理完成
    		// reject('失败') // 数据处理出错  
    	});
    }
    
    var b = funcA("123", "456").then(
      (res) => {console.log(res)},  // 成功
      (err) => {console.log(err)} // 失败
    )
    
    var funcA = function (a, b) {
    	//to do some things
    	console.log(a+b);
    	return new Promise( (resolve, reject) => {
    		//to do some things 例如:一段耗时的异步操作
    		console.log(a, b);
    		resolve('成功') // 数据处理完成
    		// reject('失败') // 数据处理出错  
    	});
    }
    
    var b = funcA("123", "456").then(
      (res) => {console.log(res)},  // 成功
      (err) => {console.log(err)} // 失败
    )
    

    2类状态变更的处理: resolve / reject

    • 一旦状态改变就不会再变 (两种状态改变:成功或失败)

      • Pending(进行中) -> Fulfilled(已成功)
      • Pending(进行中) -> Rejected(已失败)
    • resolve

    作用: 将Promise对象的状态从“未完成(pending)”变为“成功(resolved)”。
    在异步操作成功时调用,并将异步操作的成功结果作为参数传递出去;

    • reject

    作用:将Promise对象的状态从“未完成(pending)”变为“失败(rejected)
    在异步操作失败时调用,并将异步操作报出的错误信息作为参数传递出去。

    Promise对象的3个状态

    • 对象的状态不受外界影响 (3种状态)
      • Pending 状态(进行中)
      • Fulfilled 状态(已成功)
      • Rejected 状态(已失败)

    then

    Promise实例/对象生成后,可用then方法分别指定两种状态变更处理(resolve/reject)的回调参数。then 方法可以接受两个回调函数作为参数:

    • Promise对象状态改为Resolved时调用 (必选)
    • Promise对象状态改为Rejected时调用 (可选)
    function sleep(ms) {
        return new Promise(function(resolve, reject) {
            setTimeout(resolve, ms);
        })
    }
    
    sleep(500).then( ()=> console.log("finished"));
    

    这段代码定义了一个函数sleep,调用后,等待了指定参数(500)毫秒后执行then中的函数。值得注意的是,Promise新建后就会立即执行。

    执行顺序

    接下来我们探究一下它的执行顺序,看以下代码:

    let promise = new Promise(function(resolve, reject){
        console.log("AAA");
        resolve()
    });
    promise.then(() => console.log("BBB"));
    console.log("CCC")
    
    // AAA
    // CCC
    // BBB
    

    执行后,我们发现输出顺序总是 AAA -> CCC -> BBB
    表明:在Promise新建后会立即执行,所以首先输出 AAA。然后,then方法指定的回调函数将在当前脚本所有同步任务执行完后才会执行,所以BBB 最后输出。

    4 示例

    示例1:最简单示例

    new Promise(resolve => {
      setTimeout(() => {
        resolve('hello')
      }, 2000)
    }).then(res => {
      console.log(res)
    })
    

    示例2: 分两次,顺序执行

    new Promise(resolve => {
        setTimeout(() => {
          resolve('hello')
        }, 2000)
    }).then(val => {
        console.log(val) //  参数val = 'hello'
        return new Promise(resolve => {
          setTimeout(() => {
            resolve('world')
          }, 2000)
        })
    }).then(val => {
        console.log(val) // 参数val = 'world'
    })
    

    示例3:promise完成后then()

    let pro = new Promise(resolve => {
       setTimeout(() => {
         resolve('hello world')
       }, 2000)
    });
    
    
    setTimeout(() => {
       pro.then(value => {
       console.log(value) // hello world
     })
    }, 2000);
    

    结论:promise作为队列最为重要的特性,我们在任何一个地方生成了一个promise队列之后,我们可以把他作为一个变量传递到其他地方。

    X 参考文献

    赞赏-支付宝二维码
    本文作者千千寰宇
    本文链接 https://www.cnblogs.com/johnnyzen
    关于博文:评论和私信会在第一时间回复,或直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:若本文对您有帮助,可点击右下角推荐一下。您的鼓励、【赞赏】(左侧赞赏支付码)是博主技术写作的重要动力!
  • 相关阅读:
    C++ 编译时字符串加密
    c#自动修复缺损和不规范的html
    C#下载网络资源(网页或文件)
    yum install 命令下载安装离线包
    C# Sql Server 数据库 传递 表值参数
    cximage 裁剪图片并背景透明
    centos 7.5 编译并运行 opencv 4.5.1 c++
    c++ freeimage 指定颜色透明
    c++ string 大小写转换
    opencv 裁剪图像
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/15189042.html
Copyright © 2011-2022 走看看