资讯专栏INFORMATION COLUMN

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

JayChen / 2363人阅读

摘要:前段的功能越来越强大,现在实现同步的循环输出的方式也越来越多,我们先看一个例子后输出相信大家对这个比较常见了,原理是因为声明的为的局部变量,只是定时器,他暂时将内部函数挂起,等到一秒后执行,到那个时候,已经变成了。后续会更新,欢迎补充

前段的功能越来越强大,现在实现同步的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的知识点百度也很多,可自行百度。

后续会更新,欢迎补充

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93271.html

相关文章

  • 理解Koa洋葱模型

    摘要:的嵌套就像是洋葱模型的形状就是一层包裹着一层,直到到最里面一层的的值返回。中间件引擎是有模块来实现的,也就是实现洋葱模型的核心引擎。表示遍历还没有结束。 中间件特性 | | | ...

    yearsj 评论0 收藏0
  • 异步等待的 Python 协程

    摘要:辅之以事件循环,协程可用于异步处理,尤其是在中。当前支持的协程基于增强型生成器,于版本开始采用。新的特性中,异步还有两种新用途异步内容管理器和迭代器。 现在 Python 已经支持用协程进行异步处理。但最近有建议称添加协程以全面完善 Python 的语言结构,而不是像现在这样把他们作为生成器的一个类型。此外,两个新的关键字———异步(async)和等待(await),都该添加到 Pyt...

    NicolasHe 评论0 收藏0
  • 【JS基础】ES6语法

    摘要:遍历器对象调用方法后,抛出的异常被函数体捕获以后,会附带执行下一条语句。 iterator迭代器 在ES6之前遍历数组的方法有以下四种: // 第一种 for(var i = 0; i < array.length; i++){ console.log(array[i]) } // 第二种 array.forEach(function(item,index){ cons...

    Maxiye 评论0 收藏0
  • 通读Python官方文档之协程、Future与Task

    摘要:所以在第一遍阅读官方文档的时候,感觉完全是在梦游。通过或者等待另一个协程的结果或者异常,异常会被传播。接口返回的结果指示已结束,并赋值。取消与取消不同。调用将会向被包装的协程抛出。任务相关函数安排协程的执行。负责切换线程保存恢复。 Tasks and coroutines 翻译的python官方文档 这个问题的恶心之处在于,如果你要理解coroutine,你应该理解future和tas...

    mgckid 评论0 收藏0
  • Javascript关于异步编程的发展

    摘要:前言转简体重新排版布局代码全面使用并且直接附上输出结果补充细节补充内容增加例子说明新增和在遍历情况下怎么使用上文讲了关于执行机制单线程同异步任务事件循环的知识点我们知道在某一时刻内只能执行特定的一个任务并且会阻塞其它任务执行为了解决这个 前言 PS:2018/08/08 转简体2018/08/09 重新排版布局,代码全面使用ES6并且直接附上输出结果,补充细节2018/08/13 补充...

    princekin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<