一起来学习javascript-Promise

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

 <button οnclick="test">点击</button>

</body>

</html>

<script>

// Promise 是 JavaScript 中的一个对象,用于异步计算的一个解决方案,以更易于管理和维护的方式处理异步操作,避免了传统的回调地狱(callback hell)问题。Promise代表一个现在、将来或永远可能可用,或者永远不会可用的值。

// 基本概念

// 状态:Promise有三种状态——pending(等待中)、fulfilled(已成功)和rejected(已失败)。状态一旦从pending变为fulfilled或rejected,就不会再改变。

// 构造函数:创建Promise实例需要通过new Promise(executor),其中executor是一个函数,接受两个参数resolve和reject,分别在异步操作成功和失败时被调用。

// 在JavaScript的世界中,所有代码都是单线程执行的。

// 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:

function add(){

    console.log("我要过一会儿在执行add函数")

}

console.log('before setTimeout()');

 setTimeout(add,3000)// 3秒钟后调用add函数

console.log('after setTimeout()');

// 这种情况则是体现异步的过程,边执行边等待

// 写一个异步函数

// 生成一个0-2之间的随机数,如果小于1,则等待一段时间后返回成功,否则返回失败:

function test(resolve, reject) {

    var timeOut = Math.random() * 2;

   console.log('set timeout to: ' + timeOut + ' seconds.');

    setTimeout(function () {

        if (timeOut < 1) {

           console.log('call resolve()...');

            resolve('200 OK');

        }

        else {

            console.log('call reject()...');

            reject('timeout in ' + timeOut + ' seconds.');

        }

    }, timeOut * 1000);

}

// resolve, reject这里是两个函数作为参数,

// 下面是在test()函数中调用的函数,在使用Promise对象时需要将其注释掉

// test(

//     function (result) { // 成功的回调

//         console.log('Success:', result);

//         //如果timeOut<1, console.log('call resolve()...');,我们将调用resolve('200 OK'),此时result=200 OK

//     },

//     function (error) { // 失败的回调

//         console.error('Error:', error);

//         //如果timeOut!=1,console.log('call reject()...');我们将调用reject('timeout in ' + timeOut + ' seconds.')。此时error=timeout in timeOut seconds.

//     }

// );

// 可以看出,test()函数只关心自身的逻辑,并不关心具体的resolve和reject将如何处理结果。

// 有了执行函数,我们就可以用一个Promise对象来执行它,并在将来某个时刻获得成功或失败的结果

// 链式调用:通过.then()和.catch()方法可以进行链式调用,处理Promise的结果或错误。

var p1 = new Promise(test);

var p2 = p1.then(function (result) {

    console.log('成功:' + result);

});

var p3 = p2.catch(function (reason) {

    console.log('失败:' + reason);

});

// 或者

// p1.then(function (result) {

//     console.log('成功:' + result);

// }).catch(function (reason) {

//     console.log('失败:' + reason);

// });

// 或者直接用promise对象进行异步操作

// let promise = new Promise((resolve, reject) => {

//   // 异步操作

// });

// resolve: 当异步操作成功完成时调用的函数,用来改变Promise的状态为fulfilled(已成功),并将操作的结果作为参数传递出去。

// reject: 当异步操作失败或者遇到错误时调用的函数,用来改变Promise的状态为rejected(已失败),并将错误原因作为参数传递出去。

// 完整示例代码

// new Promise(function (resolve, reject) {

//     log('start new Promise...');

//     var timeOut = Math.random() * 2;

//     log('set timeout to: ' + timeOut + ' seconds.');

//     setTimeout(function () {

//         if (timeOut < 1) {

//             log('call resolve()...');

//             resolve('200 OK');

//         }

//         else {

//             log('call reject()...');

//             reject('timeout in ' + timeOut + ' seconds.');

//         }

//     }, timeOut * 1000);

// }).then(function (r) {

//     log('Done: ' + r);

// }).catch(function (reason) {

//     log('Failed: ' + reason);

// });

// Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。

// 要串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码。有了Promise,我们只需要简单地写:

// job1.then(job2).then(job3).catch(handleError);


 

// 0.5秒后返回input*input的计算结果:

// function multiply(input) {

//     return new Promise(function (resolve, reject) {

//         log('calculating ' + input + ' x ' + input + '...');

//         setTimeout(resolve, 500, input * input);

//     });

// }

// // 0.5秒后返回input+input的计算结果:

// function add(input) {

//     return new Promise(function (resolve, reject) {

//         log('calculating ' + input + ' + ' + input + '...');

//         setTimeout(resolve, 500, input + input);

// 因此,当resolve函数在500毫秒后被调用时,它会接收到一个参数,该参数是input值的两倍(因为input + input)。

//     });

// }

// var p = new Promise(function (resolve, reject) {

//     log('start new Promise...');

//     resolve(123);

// });

// p.then(multiply)

//  .then(add)

//  .then(multiply)

//  .then(add)

//  .then(function (result) {

//     log('Got value: ' + result);

// });


 

// setTimeout可以看成一个模拟网络等异步执行的函数。现在,我们把上一节的AJAX异步执行函数转换为Promise对象,看看用Promise如何简化异步处理:

// ajax函数将返回Promise对象:

// function ajax(method, url, data) {

//     var request = new XMLHttpRequest();

//     return new Promise(function (resolve, reject) {

//         request.onreadystatechange = function () {

//             if (request.readyState === 4) {

//                 if (request.status === 200) {

//                     resolve(request.responseText);

//                 } else {

//                     reject(request.status);

//                 }

//             }

//         };

//         request.open(method, url);

//         request.send(data);

//     });

// }

// var log = document.getElementById('test-promise-ajax-result');

// var p = ajax('GET', '/api/categories');

// p.then(function (text) { // 如果AJAX成功,获得响应内容

//     log.innerText = text;

// }).catch(function (status) { // 如果AJAX失败,获得响应代码

//     log.innerText = 'ERROR: ' + status;

// });


 

// 有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:

// var p1 = new Promise(function (resolve, reject) {

//     setTimeout(resolve, 500, 'P1');

// });

// var p2 = new Promise(function (resolve, reject) {

//     setTimeout(resolve, 600, 'P2');

// });

// Promise.race([p1, p2]).then(function (result) {

//     console.log(result); // 'P1'

// });

// 由于p1执行较快,Promise的then()将获得结果'P1'。p2仍在继续执行,但执行结果将被丢弃。

// 如果我们组合使用Promise,就可以把很多异步任务以并行和串行的方式组合起来执行。

</script>

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Promise.all是JavaScript中的一个方法,用于将多个Promise对象封装成一个新的Promise对象。它接受一个Promise对象数组作为参数,返回一个新的Promise对象。当所有Promise对象都成功时,新的Promise对象也会成功,并返回所有Promise对象的返回值组成的数组。如果有任意一个Promise对象失败,新的Promise对象也会失败,并返回第一个失败的Promise对象的错误信息。 示例: ``` Promise.all([promise1, promise2, promise3]) .then((values) => { console.log(values); }) .catch((error) => { console.log(error); }); ``` ### 回答2: 对于这个问题,我将提供一个300字的回答来介绍如何封装一个 Promise.all函数。 Promise.all是一个用于处理多个 Promise 对象的静态方法,它接受一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。当传入的 Promise 对象数组中的所有 Promise 对象都变为 resolved 状态时,这个新的 Promise 对象才会被 resolve,并传递一个包含所有 resolved 值的数组。如果传入的 Promise 对象数组中有任一一个 Promise 对象被 reject,则新的 Promise 对象将被 reject,并传递第一个 reject 值。 要封装一个 Promise.all函数,我们可以创建一个新的 Promise 对象,并在其中进行相关的处理逻辑。首先,我们需要判断传入的参数是否为一个 Promise 对象数组,如果不是,则直接返回一个被 reject 的 Promise 对象,并传递一个对应的错误信息。 接下来,我们可以使用一个计数器来统计所有 Promise 对象的 resolved 状态。我们可以使用一个变量来保存所有 resolved 值,并在每个 Promise 对象 resolve 时将其添加到这个变量里。同时,在任何一个 Promise 对象被 reject 时,我们需要立即 reject 整个新的 Promise 对象,并传递对应的 reject 值。 最后,当所有 Promise 对象都变为 resolved 状态时,我们可以 resolve 新的 Promise 对象,并传递保存的所有 resolved 值。 总结起来,封装一个 Promise.all函数需要进行参数验证、计数器和变量的初始化、处理每个 Promise 对象的 resolved 和 reject 状态,并最终返回一个新的 Promise 对象。这个过程可以通过创建一个匿名函数,使用上述逻辑来实现。这样我们就能够使用封装好的 Promise.all函数来处理多个 Promise 对象的结果了。 ### 回答3: Promise.all 是 JavaScript 中的一个方法,它接收一个 Promise 数组作为参数,并在所有 Promise 都完成时返回一个新的 Promise 对象。 如果要封装一个 Promise.all 方法,可以采用以下的方式: ```javascript function myPromiseAll(promises) { return new Promise((resolve, reject) => { let results = []; let counter = 0; if (promises.length === 0) { resolve(results); } else { for (let i = 0; i < promises.length; i++) { promises[i].then((result) => { results[i] = result; counter++; if (counter === promises.length) { resolve(results); } }).catch((error) => { reject(error); }); } } }); } ``` 这个方法首先创建一个新的 Promise 对象,并接收一个 promises 数组作为参数。然后创建一个空数组来存储每个 Promise 的结果,以及一个计数器来跟踪已完成的 Promise 数量。 接下来,判断传入的 promises 数组是否为空。如果为空,直接使用 resolve 返回空数组。 如果 promises 数组不为空,循环遍历数组中的每个 Promise 对象。当每个 Promise 对象都调用了 then 方法时,将该 Promise 的结果存储到 results 数组的对应位置中,并增加计数器的值。当计数器的值等于 promises 数组的长度时,说明所有 Promise 已经完成,此时使用 resolve 返回结果数组。 如果其中任意一个 Promise 出现错误,则使用 catch 方法将错误传递给新的 Promise 对象,并使用 reject 返回错误。 这样,我们就成功封装了一个 Promise.all 方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值