关于微信小程序中es6-promise的应用

应用promise背景

由于我们公司需要开发微信小程序,并且小程序API大部分都是异步的API,不采用promise的话,将会出现代码一个嵌套一个的情况。如下所示:

A(){
	B(){
		C(){
		}
	}
}

这种代码结构非常不利于阅读,为此我网上了解了下,发现promise可以让异步调用 进行同步顺序向下执行。

es6与Promise的关系

  1. ES6, 全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版。
  2. promise是es6中的一个组成部分。

了解主流浏览器对promise的兼容

对于前端需要了解的就是浏览器支不支持promise了,这样我们才能确定到底要不要采用promise。
浏览器兼容性
经过查阅,微信小程序支持es6的promise,点此查看

记录一些自己对promise的理解

  1. 网上已经有很多的大神介绍promise了,阮一峰 promise入门,下面我就简单记录下简单入门和一些注意点。
  2. 首先下载 es6-promise,放进微信小程序项目中。
  3. 基本知识:
    (1) promiseg概念
    是异步编程的一种解决方案。
    从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
    (2) Promise 的状态和特点
    Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。
const p1 = new Promise(function(resolve,reject){
  resolve('success1');
  resolve('success2');
});
 
const p2 = new Promise(function(){
  resolve('success3');
  reject('reject');
});
 
p1.then(function(value){
  console.log(value); // 输出 success1
});
p2.then(function(value){
  console.log(value); // 输出 success3
});

(3) Promise 的 then 方法
then 方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。
通过 .then 形式添加的回调函数,不论什么时候,都会被调用。

const p = new Promise(function(resolve,reject){
  resolve('do_success');
  //reject('do_fail');
});
 
p.then( success => {
  console.log(success);
}, fail => {
	console.log(fail);
}
);
 
console.log('first');
// first
// do_success

(4) promise的链式执行顺序
网上介绍的promise 的then方法为 同步还是异步函数的执行顺序,讲解的并不是很齐全,这边我整理了一下。

(1)
const p = new Promise(function(resolve,reject){
  setTimeout(
    console.log("first"), 3000  
    resolve(1); //必须加在异步执行结束之后
  );
  
}).then(function(value){ // 第一个then // 1
  console.log(value); //第一个then里面的函数执行,必定是在p执行成功后才会执行。如果p执行失败(改为reject)会直接跳到catch
  return value * 2;
}).then( value => { // 第二个then // 2
  console.log(value);
}).then(function(value){ // 第三个then // undefined
  console.log(value);
  return Promise.resolve('resolve'); 
}).then(function(value){ // 第四个then // resolve
  console.log(value);
  return Promise.reject('reject'); 
}).then(function(value){ // 第五个then //不执行
  console.log('resolve:' + value);
}).catch(function(value){ // catch // catch: reject
  console.log('catch:' + value);
})
(2) then 里面放 异步函数并不能让该异步函数顺序执行下来。
异步函数里面经过promise封装,把resolve或reject 放在异步执行完后面,这样才能顺序执行下来。
const p = new Promise(function(resolve,reject){
  setTimeout(function() {
    console.log('s1');
    resolve(1);  //需要放setTimeout里面这样才能顺序执行到 then
  }, 3000);
}).then(function(value){
   setTimeout(function() {
    console.log('s2');
   }, 1000);      //s2并不会比s3早输出,需要经过封装
}).then( value => { 
 setTimeout(function() {
    console.log('s3');
   }, 500);
})

执行结果
> "s1"
> "s3"
> "s2"

调用模型:

//引入Promise js文件
const Promise = require('../../es6/es6-promise.min.js')
(1) 创建带有Promise的函数
function ptest(){
	return new Promise(function (resolve, reject) {
	//执行结束
		resolve(res) //给调用ptest的链式向下执行
		reject(res)  //给调用ptest的链式直接跳到 catch 中
	}
}
(2) 调用带有Promise的函数,用于同步执行函数
ptest
.then(function(res){
	return A()
})
.then(function(res){
	console.log(res) //A函数前必须加return, 这里才能打印出A的返回结果
	return B()
})
.catch(function(res){
	//执行ptest、A、B过程中 带有reject(或者执行失败),就跳到这里来
})
.finally(function(res){
	//最后都会执行这个
})
//类似try catch finally 结构
(3) 调用不带Promise的函数,用于同步执行函数
var promise1 = new Promise(function(resolve, reject) {
 	// setTimeout为异步函数, 这里使用Promise封装
 	console.log("test0");
	setTimeout(function() {
    	resolve('test1');
	}, 300);
});

promise1.then(function(res) {
	console.log(res);
  	return "test2"
})
.then(function(res) {
  	console.log(res);
})
.catch(function(res) {
  	console.log(res);
})

console.log("test3");
·······················································
//执行结果:
> "test0"
> "test3"     //请注意test3,比then先执行,
> "test1"
> "test2"  (为了让test1比test2先输出,必须使用promise封装)
·······················································
(4) 调用不带Promise的函数, !!!不可用
 const p = Promise.resolve();
 p.then(function () {
  setTimeout(function() {
    console.log('1');
  }, 2000);
})
.then(function () {
  console.log('2');
})
·······················································
//执行结果:
> "2"
> "1"
请注意,这种方法并不能让异步的顺序执行。
·······················································

异步函数顺序执行

// 异步函数a
var a = function () {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log("log-a")
      	setTimeout(function () {
      		console.log("log-aa")
      		resolve('a')
    	}, 2000)
    }, 2000)
  })
}

// 异步函数b
var b = function (data) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log("log-b")
      resolve(data + 'b')         
    }, 1500)
  })
}

// 异步函数c
var c = function (data) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log("log-c")
      resolve(data + 'c')
    }, 500)
  })
}

a()
  .then(function (data) {
    return b(data)
  })
  .then(function (data) {
    return c(data)
  })
  .then(function (data) {
    console.log(data)// abc
  })

嵌套关系的promise,执行顺序

从下面的例子可以看出,promise1 的链对应自己的catch
promise2 的链对应自己的catch。

var promise1 = new Promise(function(resolve, reject) {
    	resolve('test1');
});

var promise2 = new Promise(function(resolve, reject) {
    	reject('test1');
});

promise1.then(function(res) {
  	return "test2"
})
.then(function(res) {  
  	promise2.then(res =>{
      	console.log("promise2 then");
    }).catch(res =>{
        console.log("promise2 catch");
    })
})
.catch(function(res) {
  	console.log("final catch");
})

执行结果:
> "promise2 catch"

链式调用中的then怎么中断

A.then(
		if( a == 1)
			return "test" //向下执行
		else
		{
			    throw err    停止,不跳转catch
				return Promise.reject('reject');  //停止,跳转catch
	    }
			
)
.then(
)
.then(
)
.then(
)
.catch(
)

阮一峰 promise入门
mozilla promise教学
ES6 Promise 对象(推荐初学者看这个)
setTimeout async promise执行顺序总结
构建Promise队列实现异步函数顺序执行

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页