分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

js中的异步与同步,解决由异步引起的问题

发布时间:2023-09-06 01:16责任编辑:傅花花关键词:js

之前在项目中遇到过好多次因为异步引起的变量没有值,所以意识到了认识js中同步与异步机制的重要性

在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程。

下面是js几种最常见的异步情况:

  1. 异步函数 setTimeout和setInterval
    异步函数,如setTimeout和setInterval,被压入了称之为Event Loop的队列。
    setTimeout:在指定的毫秒数后,将定时任务处理的函数添加到执行队列的队尾。所以有时候也可以使用setTimeout解决异步带来的问题
    setInterval:按照指定的周期(以毫秒数计时),将定时任务处理函数添加到执行队列的队尾。

    Event Loop是一个回调函数队列。当异步函数执行时,回调函数会被压入这个队列。JavaScript引擎直到异步函数执行完成后,才会开始处理事件循环。这意味着JavaScript代码不是多线程的,即使表现的行为相似。事件循环是一个先进先出(FIFO)队列,这说明回调是按照它们被加入队列的顺序执行的。
  2. ajax
  3. node.js中的许多函数也是异步的

解决由的js异步引起的问题办法:

  1. 命名函数
    清除嵌套回调的一个便捷的解决方案是简单的避免双层以上的嵌套。传递一个命名函数给作为回调参数,而不是传递匿名函数
    例:
     1 var fromLatLng, toLatLng; 2 var routeDone = function( e ){ 3 ????console.log( "ANNNND FINALLY here‘s the directions..." ); 4 ????// do something with e 5 }; 6 var toAddressDone = function( results, status ) { 7 ????if ( status == "OK" ) { 8 ????????toLatLng = results[0].geometry.location; 9 ????????map.getRoutes({10 ????????????origin: [ fromLatLng.lat(), fromLatLng.lng() ],11 ????????????destination: [ toLatLng.lat(), toLatLng.lng() ],12 ????????????travelMode: "driving",13 ????????????unitSystem: "imperial",14 ????????????callback: routeDone15 ????????});16 ????}17 };18 var fromAddressDone = function( results, status ) {19 ????if ( status == "OK" ) {20 ????????fromLatLng = results[0].geometry.location;21 ????????GMaps.geocode({22 ????????????address: toAddress,23 ????????????callback: toAddressDone24 ????????});25 ????}26 };27 GMaps.geocode({28 ????address: fromAddress,29 ????callback: fromAddressDone30 });

     async.js 库可以帮助我们处理多重Ajax requests/responses,如:

     1 async.parallel([ 2 ????function( done ) { 3 ????????GMaps.geocode({ 4 ????????????address: toAddress, 5 ????????????callback: function( result ) { 6 ????????????????done( null, result ); 7 ????????????} 8 ????????}); 9 ????},10 ????function( done ) {11 ????????GMaps.geocode({12 ????????????address: fromAddress,13 ????????????callback: function( result ) {14 ????????????????done( null, result );15 ????????????}16 ????????});17 ????}18 ], function( errors, results ) {19 ????getRoute( results[0], results[1] );20 });
  2. 使用promise
    promise在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了:

    promise还可以做若干个异步的任务,例:有一个异步任务,需要先做任务1,如果任务成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。
    job1.then(job2).then(job3).catch(handleError);  //job1job2job3都是Promise对象

    例:
     1 ‘use strict‘; 2 ?3 var logging = document.getElementById(‘test-promise2-log‘); 4 while (logging.children.length > 1) { 5 ????logging.removeChild(logging.children[logging.children.length - 1]); 6 } 7 ?8 function log(s) { 9 ????var p = document.createElement(‘p‘);10 ????p.innerHTML = s;11 ????logging.appendChild(p);12 }13 // 0.5秒后返回input*input的计算结果:14 function multiply(input) {15 ????return new Promise(function (resolve, reject) {16 ????????log(‘calculating ‘ + input + ‘ x ‘ + input + ‘...‘);17 ????????setTimeout(resolve, 500, input * input);18 ????});19 }20 21 // 0.5秒后返回input+input的计算结果:22 function add(input) {23 ????return new Promise(function (resolve, reject) {24 ????????log(‘calculating ‘ + input + ‘ + ‘ + input + ‘...‘);25 ????????setTimeout(resolve, 500, input + input);26 ????});27 }28 29 var p = new Promise(function (resolve, reject) {30 ????log(‘start new Promise...‘);31 ????resolve(123);32 });33 34 p.then(multiply)35 ?.then(add)36 ?.then(multiply)37 ?.then(add)38 ?.then(function (result) {39 ????log(‘Got value: ‘ + result);40 });

    关于promise的两个方法

     1 var p1 = new Promise(function (resolve, reject) { 2 ????setTimeout(resolve, 500, ‘P1‘); 3 }); 4 var p2 = new Promise(function (resolve, reject) { 5 ????setTimeout(resolve, 600, ‘P2‘); 6 }); 7 // 同时执行p1和p2,并在它们都完成后执行then: 8 Promise.all([p1, p2]).then(function (results) { 9 ????console.log(results); // 获得一个Array: [‘P1‘, ‘P2‘]10 });
    1 var p1 = new Promise(function (resolve, reject) {2 ????setTimeout(resolve, 500, ‘P1‘);3 });4 var p2 = new Promise(function (resolve, reject) {5 ????setTimeout(resolve, 600, ‘P2‘);6 });7 Promise.race([p1, p2]).then(function (result) {8 ????console.log(result); // ‘P1‘9 });
    //由于p1执行较快,Promise的then()将获得结果‘P1‘p2仍在继续执行,但执行结果将被丢弃。

本文参考:

http://blog.csdn.net/u013063153/article/details/52457307

https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000

js中的异步与同步,解决由异步引起的问题

原文地址:http://www.cnblogs.com/zhuchenglin/p/7651990.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved