前端基础-异步3

3.7 Promise.all

参考答案:

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。

解析:

语法

Promise.all(iterable);

参数

  • iterable

    一个可迭代对象,如 ArrayString

返回值

  • 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise
  • 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise。注意:Google Chrome 58 在这种情况下返回一个已完成(already resolved)状态的 Promise
  • 其它情况下返回一个处理中(pending)Promise。这个返回的 promise 之后会在所有的 promise 都完成或有一个 promise 失败时异步地变为完成或失败。 见下方关于“Promise.all 的异步或同步”示例。返回值将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。

3.8 与promise.all相反的是哪一个

参考答案:

Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

扩展:

语法

Promise.race(iterable);

参数

  • iterable

    可迭代对象,类似Array

返回值

​ 一个待定的 Promise]只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值, 从而异步地解析或拒绝(一旦堆栈为空)。

3.9 promise实现文件读取

参考答案:

封装异步读取文件操作

  • fs.readFile()方法用于异步读取文件(node核心模块)
  • 将Promise的实例对象作为函数的返回值返回
  • 这样函数执行完毕后就得到一个Promise对象的实例,可以通过.then方法传入成功的回调和失败的回调
const fs = require('fs');
const path = require('path');

function asyncGetFileByPath(p) {
    return new Promise((resolve, reject) => {
        // Promise对象里面的参数,会立即执行(前面说过)
        fs.readFile(path.join(__dirname, p), 'utf-8', (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    })
}
asyncGetFileByPath('./files/1.txt')
    .then(
        (data) => { // 成功的回调
            console.log(data);
        },
        (err) => { // 失败的回调
            console.error(err);
        }
    )

解决回调地狱

  • 前面已经成功的封装了一个读取文件的函数
  • 下面用它来体验一下读取多个文件
  • 我们在.then()方法中,第一个参数resolve()方法中,返回一个promise对象B.
  • 那么在执行.then()的resolve()方法完毕后,此时的执行环境是这个Promise的实例b
  • 可以通过b的.then()方法继续传入resolve取消回调地狱,让代码趋于扁平化
const fs = require('fs');
const path = require('path');

function asyncGetFileByPath(p) {
    return new Promise((resolve, reject) => {
        // Promise对象里面的参数,会立即执行(前面说过)
        fs.readFile(path.join(__dirname, p), 'utf-8', (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    })
}
asyncGetFileByPath('./files/1.txt')
    .then(
        (data) => { // 成功的回调    '1.txt'
            console.log(data); // 打印出 1.txt 数据
            return asyncGetFileByPath('./files/2.txt')
        },
        (err) => { // 失败的回调
            console.error(err);
        }
    )
    .then( // 成功的回调  '2.txt'
        (data) => {
            console.log(data); // 打印出 2.txt 中的数据
            return asyncGetFileByPath('./files/3.txt') // 继续返回Promise对象的实例
        },
        (err) => {
            console.error(err);
        }
    )
    .then(
        (data) => { // 成功的回调 '3.txt'
            console.log(data); // 打印出 3.txt 中的数据
        },
        (err) => {
            console.error(err);
        }
    )

3.10 用js实现sleep,用promise

参考答案:

function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

const t1 = +new Date()
sleep(3000).then(() => {
  const t2 = +new Date()
  console.log(t2 - t1)
})

优点:这种方式实际上是用了 setTimeout,没有形成进程阻塞,不会造成性能和负载问题。

缺点:虽然不像 callback 套那么多层,但仍不怎么美观,而且当我们需要在某过程中需要停止执行(或者在中途返回了错误的值),还必须得层层判断后跳出,非常麻烦,而且这种异步并不是那么彻底,还是看起来别扭

3.11 实现一个 Scheduler 类,完成对Promise的并发处理,最多同时执行2个任务

参考答案:

class Scheduler {
    constructor() {
        this.tasks = [], // 待运行的任务

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

前端岗位面试真题宝典 文章被收录于专栏

本面试宝典均来自校招面试题目大数据进行的整理

全部评论

相关推荐

12-24 20:46
武汉大学 Java
点赞 评论 收藏
分享
给🐭🐭个面试机会...:我擦seed✌🏻
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务