好程序员web前端教程分享怎么用promise解决回调和异步

好程序员web前端教程分享怎么用promise解决回调和异步
首先让我们看看下面这题输出什么?

setTimeout(function() {
      console.log(1);
},1000)
console.log(2);

我们得到的结果是:先输出2,后输出1;这是什么原因呢?大家应该都知道定时器是异步的;所以先先输出2;
那么我们的需求来了,怎么先输出1,然后输出2呢?

function foo(callback) {
setTimeout(function() {
    console.log(1);
    callback();
},1000)
}
foo(function() {
      console.log(2);
})

现在我们看看打印的结果吧,果然先输出的1,然后输出2了;这个是通过回调函数解决的;
现在我么你的需求变了,我们每隔1秒后做一次输出;

function foo(callback) {
    setTimeout(function() {
        console.log(‘1秒后输出‘);
        callback()
    }, 1000)
}
foo(function() {
    console.log(‘第一次输出‘);
    foo(function() {
        console.log(‘第二次输出‘);
        foo(function() {
            console.log(‘第二次输出‘);
        })
    })
})

这样是不是解决我们的问题了呢?

是的,但是如果我们多来几次,大家会不会发现回调的太多了吗?这就是大家所说的毁掉地狱;

###所以ES6给我们提供了一个解决毁掉地狱的方法:promise;
promise是一种用异步的方式处理值的方法,promise是一个对象,解决层层嵌套问题
####promise对象的状态:

进行中: pending
成功: resovled
失败: rejected

promise对象的方法:

then() 成功后执行; 如果有两个参数:第一个参数成功后执行,第二个参数失败后执行;
catch() 失败后执行;
人promise all([]).then() 都成功后执行图then的第一个方法;
promise.race[(p1,p2,p3,---)] 只要有一个率先改变状态,promise就会执行对应的状态

var promise = new Promise(function (resolved, rejected) {
resolved(‘ok‘);
rejected(‘no‘);
//如果成功和失败同时写,执行先写的;(特点状态一旦改变,就不可逆了)
});
promise.then(function(msg) {
console.log(‘ok:‘ + msg);
},function (msg) {
console.log(‘no:‘ + msg);
});

打印结果是: ok: ok
现在我们做一个练习: 使用promise 加载一张图片;加载成功就将图片加载到body中,如果加载失败,提示失败;

var promise = new Promise(function (resolved, rejected) {
var img = document.createElement(‘img‘);
img.src = ‘./img/1.png‘;
img.onload = function () {
resolved(img)   //如果加载成功就返回resolved()
}
img.onerror = function () {
rejected(‘失败‘)    //如果加载成功就返回rejected()
}
})
promise.then(function (msg) {
document.body.appendChild(msg)
},function (msg) {
alert(msg)
})

怎么样大家是不是对promise有了了解?
那么怎么用promise解决异步的问题呢?我们还是每隔1秒后做一次输出;
```function fn() {
var promise = new Promise(function(resolved, rejected) {
setTimeout(function() {
console.log(‘每隔一秒‘);
resolved()
}, 1000)
});
return promise;
}
fn().then(function() {
console.log(‘第一次输出‘);
return fn()
}).then(function() {
console.log(‘第二次输出‘);
return fn()
}).then(function () {
console.log(‘第三次输出‘);
})

那Promise如何解决ajax回调的问题呢?咱们继续往下看.

function ajaxPromise(url) {
var promise = new Promise(function(resolved, rejected) {
var xhr = new XMLHttpRequest();
xhr.open(‘get‘, url);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
resolved( xhr.responseText); //告诉promise成功了
}
}
setTimeout(function () {//5秒后请求不到
rejected(‘error‘) //告诉promise失败了
},5000)
})
return promise;
}
document.onclick = function () {
var pro = ajaxPromise(‘data.json‘);
pro.then(function (msg) {
alert(msg) //如果路径对了,我们得到了数据
},function (msg) {
alert(msg) //如果路径错了我们弹出error
})
}

原文地址:https://blog.51cto.com/14573321/2456780

时间: 2024-10-07 10:44:54

好程序员web前端教程分享怎么用promise解决回调和异步的相关文章

好程序员web前端教程分享异步加载CSS的一些方法

好程序员web前端教程分享异步加载CSS的一些方法,在我们写页面的时候,我们做最主要的任务就是提高页面的性能和弹性加载速度,以不会延迟页面的呈现的形式来加载CSS.这是因为在默认情况下, - 浏览器会同步加载外部的CSS - 在下载和解析CSS时会影响所有页面呈现 这两种情况都会导致潜在的延迟. 当然,这也是在开始渲染页面之前,应该至少加载网站的CSS的一部分,并且为了立即将该初始CSS添加到浏览器,我们建议内联css.对于整体数量较少的网站,仅此一项就足够了,但如果CSS很大(例如,大于15到

好程序员web前端教程分享js中的模块化一

好程序员web前端教程分享js中的模块化一:我们知道最常见的模块化方案有CommonJS.AMD.CMD.ES6,AMD规范一般用于浏览器,异步的,因为模块加载是异步的,js解释是同步的,所以有时候导致依赖还没加载完毕,同步的代码运行结束:CommonJS规范一般用于服务端,同步的,因为在服务器端所有文件都存储在本地的硬盘上,传输速率快而且稳定. 1.script标签引入 最开始的时候,多个script标签引入js文件.但是,这种弊端也很明显,很多个js文件合并起来,也是相当于一个script,

好程序员web前端教程分享前端javascript练习题之promise

好程序员web前端教程分享前端javascript练习题之promisepromise-ajax的封装function ajax(url){//创建promise对象var promise = new Promise(function(resolve,reject){//创建ajax对象if(window.XMLHttpRequest){var xhr = new XMLHttpRequest();}else{var xhr = new ActiveXObject("Microsoft.XMLH

好程序员web前端教程分享JavaScript简写方法

今天好程序员web前端教程为大家分享JavaScript简写方法,小伙伴们快来看一看吧. 1.三元操作符 当想写if...else语句时,使用三元操作符来代替. constx =20; let answer; if(x >10) { answer ='is greater'; }else{ answer ='is lesser'; } 简写: constanswer = x >10?'is greater':'is lesser'; 也可以嵌套if语句: constbig = x >10

好程序员web前端教程分享初学者搞懂i++和++i

刚学习前端的同学,在学到++运算符的时候,都是一脸的懵 var k = 10; console.log(k++ + ++k + k++) //34 var i = 10; console.log(++i + i++ + ++i) //35 console.log(i++ + ++i + i++) //43 way???为什么?为什么?为什么? 下面我们一步一步的来看: 1. var i = 10; 2 .i++; //等价于i=i+1 3 .console.log(i); //11 ###++可

好程序员web前端教程:对象

什么是对象? 对象的类型是Object. JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... javaScript中万事万物皆对象 用官方一点的语言来解释对象: 什么是对象,其实就是一种类型,即引用类型.而对象的值就是引用类型的实例.在 ECMAScript 中引用类型是一种数据结构,用于将数据和功能组织在一起.它也常被称做为类,但 ECMAScript 中却没有这种东西.虽然 ECMAScript 是一门面向对象的语言,却不具 备传统面向对象语言所支持的类等基本结构.

好程序员web前端分享前端javascript练习题一

好程序员web前端教程将会为大家持续分享前端javascript练习题系列.Math 对象 1.编写一个函数,获得一个十六进制的随机颜色的字符串(例如:#20CD4F)方法:function f2(){var str="0123456789abcdef";var color="#";for(var i=0;i<6;i++){var num=Math.floor(Math.random()*str.length);color=color+str[num];}co

好程序员web前端分享CSS文件引用的最优方法

好程序员web前端分享CSS文件引用的最优方法,在html总引入css文件的方法: 1链接式: 2导入式: 区别: 使用链接式时,会在加载页面主体部分之前加载css文件,这样现实出来的页面一开始就是带有样式效果的,而使用导入式时,会在整个页面装载完成之后再装载css文件,对于有的浏览器来说,在一些情况下,如果页面文件的体积比较大,则会出现先现实无样式的页面,闪烁一下之后再出现设置样式的效果.从浏览者的感受来说,这是使用导入式的一个缺陷.** 链接式比导入式快. 当有多个文件链接到页面的时候会导致

好程序员web前端分享css常用属性缩写

好程序员web前端分享css常用属性缩写,使用缩写可以帮助减少你CSS文件的大小,更加容易阅读.css缩写的主要规则如下: 颜色 16进制的色彩值,如果每两位的值相同,可以缩写一半,例如: #000000可以缩写为#000;#336699可以缩写为#369; 盒尺寸 通常有下面四种书写方法: property:value1; 表示所有边都是一个值value1; property:value1 value2; 表示top和bottom的值是value1,right和left的值是value2 pr