精华内容
下载资源
问答
  • 书中第四章异步编程介绍的内容比较丰富,今天读到支持序列执行Promise一节,为加深理解,将代码和体会整理如下。 让Promise支持序列执行的初衷是减少编码量。如书中所言,直接使用回调函数嵌套或者事件监听...
    书中第四章异步编程介绍的内容比较丰富,今天读到支持序列执行的Promise一节,为加深理解,将代码和体会整理如下。
    让Promise支持序列执行的初衷是减少编码量。如书中所言,直接使用回调函数嵌套或者事件监听(Emitter)会导致大量的重复或者丑陋代码。而Promise有then方法,如果级联起来,代码逻辑清楚,内容简洁。
    首先,定义Promise和Deferred对象:
    var Promise = function(){
    	this.thenQueue = [];
    	this.isPromise = true;
    };
    
    var Deferred = function(){
    	this.promise = new Promise();
    };
    这里的thenQueue用于保存then方法中的回调函数,以便在后面序列执行。然后定义Promise的then方法:
    Promise.prototype.then = function(fulfilledHandler){
    	var handler = {};
    	if(typeof fulfilledHandler === 'function'){
    		handler.fulfilled = fulfilledHandler;
    	}
    	this.thenQueue.push(handler);//放入回调函数队列
    	return this;//返回自身用于链式调用
    };

    为了简单起见,这里只实现了完成态的情况,不考虑出错失败态的情况。then方法返回Promise自身用于链式调用。然后定义Deferred的生成callback的工具函数:
    Deferred.prototype.callback = function(){
    	var that = this;
    	return function(value){
    		that.resolve(value);
    	};
    }

    该函数为异步调用生成一个回调函数,该回调会触发Deferred的resolve方法,同样未考虑reject的情况。最后定义Deferred的resolve方法:
    Deferred.prototype.resolve = function(val){
    	var promise = this.promise;
    	var handler;
    	while((handler = promise.thenQueue.shift())){
    		if(handler && handler.fulfilled){
    			var res = handler.fulfilled(val);
    			if(res && res.isPromise){
    				res.thenQueue = promise.thenQueue;//将queue中剩余回调转交给后续promise
    				this.promise = res;
    				return;
    			}
    		}
    	}
    };

    while循环从当前deferred对象的promise维护的回调队列中按顺序取出回调函数并执行,如果回调函数的返回值仍然是Promise,则将当前thenQueue赋值给该返回Promise,并将当前Deferred的promise对象更新为返回的Promise(为后续resolve做准备),然后立即返回(因为要按序执行,刚刚返回的promise还没有resolve,不能继续处理后续then的回调)。如果回掉函数的返回值不是Promise,则继续处理后续的then回调函数。下面举个例子:
    var getValue = function(name, callback){
    	var map = {
    		'cat': 'july',
    		'july': 'jay'
    	};
    	setTimeout(function(){
    		callback(map[name]);
    	}, 500);
    };
    首先定义一个函数模拟异步调用,该函数通过一个name获取一个value,500毫秒返回结果。然后定义两个函数调用getValue方法,要求第二个函数调用依赖于第一个函数调用的返回结果,如:
    var testValue1 = function(name){
    	var deferred = new Deferred();
    	getValue(name, deferred.callback());
    	return deferred.promise;
    };
    
    var testValue2 = function(name){
    	var deferred = new Deferred();
    	getValue(name, deferred.callback());
    	return deferred.promise;
    };
    
    testValue1('cat').then(function(value1){
    	//第二次调用依赖于第一次的结果
    	return testValue2(value1);
    }).then(function(value2){
    	//输出'jay'
    	console.log(value2);
    }).then(function(){
    	//该调用不依赖于前面结果,但也需等到前面调用完毕才能执行
    	console.log('Hello Cat');
    });

    testValue1异步调用结束后获得value1,然后调用testValue2,并传入value1。testValue2返回一个Promise,并进一步返回给resolve方法中的res变量,按照前面所述逻辑,此时testValue2放回的Promise维护的队列更新为新的队列(里面除去第一个then回调,还有两个函数待执行)。当第二个getValue结束后,输出结果'jay',没有返回值。因此在resolve方法中res的值是undefined,while循环会继续执行,取出最后一个then回调,执行之输出'Hello Cat',此时仍无返回值,且队列为空,程序结束。
    另外,虽然后两次then回调没有返回Promise,但是如果后续调用依赖于testValue2的结果value2,仍然可以继续调用then方法,如:
    testValue1('cat').then(function(value1){
    	//第二次调用依赖于第一次的结果
    	return testValue2(value1);
    }).then(function(value2){
    	//输出'jay'
    	console.log(value2);
    }).then(function(){
    	//该调用不依赖于前面结果,但也需等到前面调用完毕才能执行
    	console.log('Hello Cat');
    }).then(function(value2){
    	//仍然输出'jay'
    	console.log(value2);
    });

    可以这样的做的原因是当前while循环仍然是resolve value2时的循环,依次在执行回调,value2依然可见。因此,如果后续调用不返回新的Promise,则一直可以依赖value2。而value1已经不可见,这是由调用的依赖关系决定的。
    这种模式的好处是,简单明了地定义了多个异步调用顺序执行的逻辑,但即使两个调用之间没有依赖关系,仍然是顺序执行(如后两个then回调)。


    展开全文
  • Sequence as Promise执行函数的数组作为序列并返回promise
  • Promise.all方法顺序执行 前言 前端的异步请求的顺序化 一、异步请求需要序列化情况举例 前端渲染数据之前,可能需要预先读取规则型数据来替换渲染的数据。 需要按照顺序执行方法 二、解决方法 1.需要先执行的方法...



    前言

    前端的异步请求的顺序化

    一、异步请求需要序列化情况举例

    前端渲染数据之前,可能需要预先读取规则型数据来替换渲染的数据。
    需要按照顺序执行方法

    二、解决方法

    1.需要先执行的方法套在Promise中 e.g.读取规则数据

          getDic () {
          //先执行的方法套在Promise方法中
            return new Promise((resolve, reject) => {
            //我们需要写的,e.g.读取规则数据
              sysdictdata.listGet({ 'dictType': 'dic_sys_user_sex' })
                .then(({data}) => {
                  if (data && data.code === 0) {
                    data.page.list.forEach(value => {
                    //这里是我想要的结果,需要在下一个方法执行前执行完
                      this.dic_sys_user_sex[value.dictValue] = value.dictLabel
                    })
                  }
                })
                //尤其注意,必须要写resolve(),否则失败,这里是注意点一
              resolve()
            })
          }
    

    2.写好后序需要执行的方法 e.g.需要渲染的方法

          getDataList () {
            this.dataListLoading = true
            var scs = {}
            teacher.listGet(scs).then(({data}) => {
              if (data && data.code === 0) {
                this.dataList = data.page.list
                this.dataList.forEach(value => {
                //这里就需要用到方法一中读取到的数据
                  value.sex = this.dic_sys_user_sex[value.sex]
                })
              } else { this.dataList = [] }
            })
          }
    

    3.用Promise.all方法顺序执行

    //一定要记得Promise.all方法的参数用方括号[]括起来,这里是注意点二
    created () { Promise.all([this.getDic()]).then(res => { this.getDataList() }) },
    

    p.s.两个注意点的细节没有注意到浪费了大量的时间
    完成

    展开全文
  • 关于Promise和setTimeout执行顺序的问题,先看一道题: 写出console.log输出的值: console.log('one'); setTimeout(function(){ console.log('two'); },0); Promise.resolve().then(function(){ ...

    关于Promise和setTimeout执行顺序的问题,先看一道题:

    写出console.log输出的值:

    		console.log('one');
    		setTimeout(function(){
    			console.log('two');
    		},0);
    		Promise.resolve().then(function(){
    			console.log('three');
    		})
    		console.log('four')
    		// 以下是打印结果
    		// 'one'
    		// 'four'
    		// 'three'
    		// 'two'
    
    

    分析一下代码的执行过程:

    1. 所有的代码都是在script标签中的,这是第一个宏任务。
    2. 代码从上到下同步解析,先打印’one’出来。
    3. 接着是setTimeout,第二个宏任务
    4. 接着遇到Promise,这是第三个宏任务,排队。
    5. Promise的回调,是一个微任务,微任务序列中排队。
    6. 打印‘four’出来。
    7. 执行微任务,打印‘three’。
    8. 执行宏任务,打印’two’。
    9. 所以最后的结果是 ‘one’ ‘four’ ‘three’ ‘two’
    展开全文
  • Promise的顺序执行

    千次阅读 2016-02-05 14:57:30
    0x00有时候我们希望JS脚本以同步的方式执行,但是在实际情况中,很多操作是异步的,如Ajax请求后端数据,执行一些动画等。刚开始,我使用回调函数的方法,这种方式的缺点很明显,当逻辑复杂时,回调函数嵌套多层,...

    0x00

    有时候我们希望JS脚本以同步的方式执行,但是在实际情况中,很多操作是异步的,如Ajax请求后端数据,执行一些动画等。

    刚开始,我使用回调函数的方法,这种方式的缺点很明显,当逻辑复杂时,回调函数嵌套多层,造成callback hell

    $.get('http://www.a.com',function (data) {
        //deal data
        $.get('http://http://www.b.com');
    });

    后来使用Promise的then方法,在then方法中,返回一个Promise对象时,将会替换原来的对象,实现链式调用。

    $.get('http://www.a.com')
        .then(function(data) {
            //data为返回a.com的数据
            //deal data
            return $.get('http://http://www.b.com');
        }).then(function(data) {
            //data为返回b.com的数据
            //deal data
        });

    0x01

    上面的两种方法都是固定写好Promise异步操作。那假设我们的Promise对象是动态生成的,储存在一个数组,然后我需要数组中的Promise对象顺序执行呢?
    可能上面的描述比较枯燥,转换成具体的需求,我们可以想象,我们正在写一个JS动画库,动画库支持序列动画操作,用户可以传入一系列的操作,如moveLeft``moveRight…,我们把这些操作看做成一个生产出promise对象的函数数组。

    
                /**
                 * 返回一个函数,此函数执行后返回一个Promise对象
                 * @param {String} id 给Promise对象一个标记
                 */
                function promiseFunc(id) {
                    return function() {
                        return new Promise(function(resolve, reject) {
                            var delayTime = Math.random() * 1000;
                            setTimeout(function() {
                                resolve([id, delayTime]);
                            }, delayTime)
                        });
                    }
                }
                var promiseFuncArr = [];
                promiseFuncArr.push(promiseFunc(0));
                promiseFuncArr.push(promiseFunc(1));
                promiseFuncArr.push(promiseFunc(2));
                promiseFuncArr.push(promiseFunc(3));
                promiseFuncArr.push(promiseFunc(4));
                var p = new Promise(function(resolve) { //先创建一个完成状态的Promise
                    resolve('start', 3434);
                });
                //依次执行数组中的函数,并将返回的Promise替换p
                for (var i = 0; i <= promiseFuncArr.length; i++) {
                    (function(i) {
                        p = p.then(function(data) {
                            console.log(data);
                            if (i == promiseFuncArr.length) {
                                return null;
                            }
                            //当i为4时,return promiseFuncArr[4]()后,循环退出,
                            //没有then方法获取promiseFuncArr[4]()的回调
                            //因此我们多循环一次
                            return promiseFuncArr[i]();
                        });
                    })(i)
                }

    执行效果
    这里写图片描述

    0x02 ES6/7 的对异步操作改进

    ES6 提供了Generator函数,ES7提供了async函数,简化了异步操作。

    展开全文
  • Promise

    2019-07-09 15:13:40
    一、Promise是什么? Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大。 ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 ES6 规定,...
  • promise

    2019-09-28 02:39:23
    当你调用一系列异步方法时,使用promise可以让多个操作按照你的想法执行,实现序列化。 Promise有3种状态: Pending:进行中 Resolved(Fulfilled):已完成 Rejected:已失败 Promise构造器接受一个函数作为...
  • JavaScript|Promise

    2021-08-15 00:05:59
    JavaScript|Promise Promise 是一个 ECMAScript 6 提供的类,...当 Promise 被构造时,起始函数会被异步执行,then()可以将当前函数添加到所属promise的异步执行序列表中: <!DOCTYPE html> <html lang="en"&g
  • 手写Promise

    2020-07-16 20:01:29
    可以将异步操作,进行队列的序列化,按照需求顺序执行 Promise的使用 我们通过setTimeout来模拟请求数据的异步操作,并且执行一个resolve结果,1秒之后.then中打印的得到的就是fulfilled字符,这就完成了一个简单...
  • Promise模式

    2019-03-26 18:05:47
    Promise模式是一种异步编程模式 。它使得我们可以先开始一个任务的执行,并得到一个用于获取该任务执行结果的凭据对象,而不必等待该任务执行完毕就可以继续执行其他操作。等到我们需要该任务的执行结果时,再调用...
  • 同时,我们又希望这些任务一起开始执行。 不需要检查这些任务何时完毕。/** * 检测一个接口,返回检测结果 * @param host * @param port * @returns {Promise} */ function detectOnePromise(hos
  • promise 拙见

    2019-10-04 02:34:38
    一,promise是什么? promise 是最早由社区提出和实现是一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和强大。 ES6 将其写进了语言标准,统一了用法,原生提供了 promise 对象。 ES6 ...
  • JavaScript之异步 - Promise (二)

    千次阅读 2017-06-10 23:11:10
    Promise的单步执行this-then-that并不是唯一的机制,我们可以将多个promise连接一起表示一系列异步步骤。 这种方式可以实行的关键在于两个Promise固有行为特性。  每次你对Promise调用then(),都会创建一个新的...
  • Promise笔记

    2021-03-28 11:16:19
    titile: Promise笔记 tags: promise Promise笔记 import Axios from 'axios'; export default { // 经纬度反向解析 regeo(params) { return new Promise((resolve, reject) => { Axios({ method: 'get', ...
  • js中的promise和async

    2021-01-12 18:57:02
    Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数,.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,.catch() 则是设定 Promise 的异常处理序列,.finally() 是...
  • promise实现递归调用

    2020-03-16 10:52:34
    想要做一个简单的AI,实现一个动作序列,等前面一个执行完毕了,再执行下一个动作 Promise&then 参考我自己的一篇帖子,记录了我自己理解promise&then的[1] 实现 直接上代码了 var dramas = [ { "time": ...
  • es6之Promise

    2020-05-21 20:11:29
    文章目录PromisePromise介绍Promise的三种状态Promise链式调用Promise方法Promise.prototype.then()Promise.prototype.catch()Promise.prototype.finally()Promise.all()Promise.prototype.race()Promise.resolve()...
  • Promise学习笔记

    2020-11-06 17:27:26
    Promise学习笔记第1章 准备1.1 区别实例对象与函数对象1.2 二种类型的回调函数1.2.1 同步回调1.2.2 异步回调1.3 JS 的 error 处理第2章 promise 的理解和使用2.1 Promise 是什么?2.1.1 理解2.1.2 promise 的状态...
  • Promise知识点

    2021-05-23 14:18:58
    promise的三个状态:pending(进行中) fulfilled(已成功) rejected(已失败) resolve:将Promise对象的状态从“未完成”变成“成功” reject:将Promise对象的状态从“未完成”变成“失败” Promise.prototype....
  • Promise的理解

    2019-10-11 19:12:34
    一、Promise是什么? Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大。 ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 ES6 规定...
  • 生成器和promise总结 1.生成器是一种不会在同事输出所有值序列的函数,而是基于每次的请求生成值。 2.不同于标准函数,生成器可以挂起和恢复它们的执行状态。当生成器生成一个值后,它将会在不阻塞主线程的基础上...
  • 在异步序列中,任意时刻只能有一个异步任务执行,如果想同时执行,怎么实现呢?可以用到 Promise.all([…]),它并不能让两个异步任务同时执行,但是可以让两个异步任务执行完了之后再让后面的流程继续执行,相对于这两...
  • Promise.all原理

    2020-04-25 16:43:10
    Promise.all()方法用于并行执行一系列异步操作,接收一个数组做参数,参数中不是promise的直接放入结果数组中,是promise的进行resolve回调。如果参数中有一个失败(rejected),则此实例回调reject,并返回第一个...
  • ES6 Promise原理

    2021-03-26 20:35:20
    Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。 图片来源 ——对于嵌套的异步操作,内层状态没有确定时,外层不会执行 如果一切都正常,则调用 resolve,否则调用 ...
  • HTML5 的 JavaScript Promise

    2018-08-20 18:05:34
    1 Promise (1)Promise是一种抽象异步处理的对象,其核心概念为“确保在一件事做完之后,再做另一件事”。 (2)浏览器支持: 到目前为止:Safari8、 Chrome 34、Firefox30、Opera20以上版本支持该对象。 2 ...
  • promise使用初探

    2018-12-29 19:43:32
    title: promise使用初探 date: 2018-12-29 16:10:48 categories: 小游戏 tags: js promise简介 Promise是异步编程的一种解决方案,比传统的解决方案 — 回调函数和事件——更合理和更强大。 为什么要用他 我们考虑...
  • JavaScript Promise API

    2016-03-01 16:04:42
    JavaScript Promise API Feb 24, 2016 Promise是抽象异步处理对象以及对其进行各种操作的组件。 本文将会详细的向你介绍如何在JavaScript中借助Promise来简化异步代码流。 Statement 作者: 景庄,We
  • Promise实现原理

    2016-01-16 00:08:00
    Promise实现原理 时间2015-06-18 10:45:43风影博客 原文http://www.chenjunxyf.me/promiseshi-xian-yuan-li/ 主题JavaScript 这两天在熟悉kissy框架的时候,看到了Promise模块。Promise对于一个Jser并...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,012
精华内容 2,804
关键字:

promise序列执行