用各种方式实现同步for循环输出(yeild, await...)

前段的功能越来越强大,现在实现同步的for循环输出的方式也越来越多,我们先看一个例子:

forF();
function forF() {
  for (var i = 0; i < 3; i++) {
    setTimeout(function () {
      console.log(i);
    }, 1000)
  }
}
// 1s后输出:3 3 3

相信大家对这个比较常见了,原理是因为var声明的i为forF的局部变量,setTimeout只是定时器,他暂时将内部函数挂起,等到一秒后执行,到那个时候,i已经变成了5。

那么我们的解决办法有哪些呢?

先上一个es5以前的解决办法:

forF();
function forF() {
  for (var i = 0; i < 3; i++) {
    outF(i);
  }
}

function outF(i) {
  setTimeout(function () {
    console.log(i);
  }, 1000*i)
}
// 0 1 2

因为在循环中用了外部函数,那么相当于创建了三个outF实例,因为i是基本变量,所以每个实例的i都是不共享的,这里要注意设置的定时器时间要1000*i;

下面开始用es6的方法实现啦! 1.用块作用域的let

forF();
function forF() {
  for (let i = 0; i < 3; i++) {
    setTimeout(function () {
      console.log(i);
    }, 1000*i)
  }
}

因为let是块作用域的,对于setTimeout函数而言,每次循环都新创建一个i,每个i不共享

2.await(其实是es7的) 见代码

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve('ok');
        }, time);
    })
};
// // 用await实现循环输出数字
async function awaitF() {
  for (var i = 0; i < 3; i++) {
    await sleep(1000);
    console.log(i)
  }
}
awaitF()
// 0 1 2

await顾名思义是等待,他接受一个promise对象,等待他相应然后才继续执行。 注意用await的函数必须加async关键字 关于promise,推荐看大白话:https://www.cnblogs.com/lvdab...

3.yeild

function* countAppleSales () {
  for (var i = 0; i < 3; i++) {
    yield;
    console.log(i);
  }
}

var appleStore = countAppleSales(); // Generator { }
appleStore.next();
nextApp(appleStore);
function nextApp(appleStore) {
  setTimeout(function () {
    let done = appleStore.next().done;
    if (!done) {
      nextApp(appleStore);
    }
  }, 1000);
}

yield函数必须定义成function* 外部在调用此函数的时候必须用next()方法他才会继续执行到下个yeild那里,所以这里用递归去执行。 关于yeild的知识点百度也很多,可自行百度。


后续会更新,欢迎补充

原文链接:segmentfault.com

上一篇:20180308_vue-router前端权限控制问题
下一篇:自荐一个由js实现的跨浏览器书签插件

相关推荐

  • 面试官:给我说说什么是同步异步?

    今天是刘小爱自学Java的第95天。 感谢你的观看,谢谢你。 话不多说,开始今天的学习: (/public/upload/3ad814429b0556984d71aff5117cfe75) 一...

    20 天前
  • 重新理解async和await

    async 和 await 在干什么 任意一个名称都是有意义的,先从字面意思来理解。async 是“异步”的简写,而 await 可以认为是 async wait 的简写。

    1 年前
  • 重学JS:async/await

    前言 异步操作一直是JS中不可或缺的一环,从最开始回调函数,到后面的Promise,再到ES2017引入的async函数,异步操作逐渐进化,变得越来越简单方便,接下来就仔细看看在ES2017引入了...

    1 年前
  • 调试时经常使用的console.log()的同步和异步问题

    最近帮助一个同学在调试问题的时候,的输出真的让我诧异了一把,因为它竟然会出现异步输出的情况,因而误导了我们的判断,找错了方向,耽误了很多时间,所以这里记录一下遇到的这个问题,加深印象。

    2 年前
  • 详解Node.js中的Async和Await函数

    在本文中,你将学习如何使用Node.js中的async函数(async/await)来简化callback或Promise. 异步语言结构在其他语言中已经存在了,像c的async/await、Kot...

    2 年前
  • 记一次小程序开发中如何使用async-await并封装公共异步请求

    前言 在平常的项目开发中肯定会遇到同步异步执行的问题,还有的就是当执行某一个操作依赖上一个执行所返回的结果,那么这个时候你会如何解决这个问题呢; 实现方案 regenerator(h...

    2 年前
  • 让你的小程序支持async-await

    asyncawait是ES7的语法,截止我写这篇文章为止,小程序还是不支持asyncawait语法的,所以需要使用regenerator(https://github.com/facebook/reg...

    2 年前
  • 解决<el-checkbox-group> 数据与UI更新不同步的坑

    Bug情景再现 得到这样的结果: clipboard.png(https://img.javascriptcn.com/03024ef1826cde68217b297ad764b756 "c...

    1 年前
  • 脚本标签同步和延迟

    surfmuggleAdam(https://stackoverflow.com/users/819887/surfmuggle)提出了一个问题:Script Tag async &amp; def...

    2 年前
  • 细说async/await相较于Promise的优势

    前言 介于上一篇 「今日头条」前端面试题和思路解析(https://segmentfault.com/a/1190000017480929) 中提到的 async/await,让我想起了之前写过的...

    2 年前

官方社区

扫码加入 JavaScript 社区