1. 程式人生 > >Node.js的那些坑(三)——如何在非同步方法都執行後再執行

Node.js的那些坑(三)——如何在非同步方法都執行後再執行

在非同步方法執行後再執行的直接解決方案就是寫回調。

可是如果想讓所有的(例如迴圈呼叫的若干次)非同步方法全部執行完之後再執行接下來的方法該怎麼辦呢?

本文基於Promise語法,給出解決方案。

接著上一篇的例子,我們先來看一下有問題的寫法。

有問題的寫法:

var request = require('request');

// 非同步獲取網路資源的方法
getWeb = (index, getCallback) => {
	var url = 'http://www.duzixi.com';

	request(url, function (error, response, body) { 
		if (!error && response.statusCode == 200) 
		{    
			getCallback(body);
			return body;
				
		} else {
			console.log(response.statusCode + " " + error);
			getCallback("");
			return "";
		}
	})
}

// 迴圈呼叫
for (var i = 0; i <= 10; i++) {
	((index)=>{
		getWeb(index, (body)=>{
			console.log(index);
		})
	})(i)
}

console.log("All done!");


神奇的執行結果:

All done!
1
2
3
0
4
6
5
7
9
8
10

原始碼最後輸出的All done! 居然出現在了最上面。

原因相比不用多說大家也知道,由於非同步方法是花費時間的,所以輸出事件後發生。

問題的解決方案:

這個問題的解決方案就是Promise,迴圈呼叫部分的原始碼修改如下:

var actions = [];  // 定義一個空的方法陣列
// 迴圈呼叫
for (var i = 0; i <= 10; i++) {
	var action = () => { // 將每一次迴圈方法定義為一個方法變數
		return new Promise(resolve =>{ // 每個方法返回一個Promise物件,第一個引數為resolve方法
			((index)=>{
				getWeb(index, (body)=>{
					console.log(index);
					resolve();          // 在方法結束時呼叫resolve()方法
				})
			})(i)

		})
	}
	actions.push(action());  // 將每次迴圈呼叫的方法新增到方法陣列中
}

Promise.all(actions).then(()=>{ // 呼叫Promise的all方法,傳入方法陣列,結束後執行then方法引數中的方法
	console.log("All done!");
});

最終的執行結果:
8
7
5
9
4
1
10
6
2
3
0
All done!


最後,感謝小紅幫助解答了該問題。

相關推薦

Node.js那些——如何在非同步方法執行執行

序 在非同步方法執行後再執行的直接解決方案就是寫回調。 可是如果想讓所有的(例如迴圈呼叫的若干次)非同步方法全部執行完之後再執行接下來的方法該怎麼辦呢? 本文基於Promise語法,給出解決方案。 接著上一篇的例子,我們先來看一下有問題的寫法。 有問題的寫法: v

149.Node.js學習筆記2018.12.03

1. 知識點 模組系統 核心模組 第三方模組 自己寫的模組 載入規則以及載入機制 迴圈載入 npm package.json Express 第三方web開發框架

一起學爬蟲 Node.js 爬蟲篇使用 PhantomJS 爬取動態頁面

今天我們來學習如何使用 PhantomJS 來抓取動態網頁,至於 PhantomJS 是啥啊什麼的,看這裡 我們這裡就不再討論 PhantomJS 的入門基礎了。下面正題 1.我們先準備,開啟瀏覽器,輸入網址 http://news.163

Node.js 依賴管理—package-lock.json詳解

end 發現 json詳解 ever arr 文章 效果 樹形結構 例如 原文鏈接:https://www.novenblog.xin/detail?id=68 本文拜讀百度@小蘑菇哥哥的Node.js 中的依賴管理,正文從這裏開始~ papackage.json no

分布式系統的那些事兒 - 系統與系統之間的調用

數據格式 轉換 處理 分布 互調 圖片處理 動作 人性 並且 系統與系統之間的調用通俗來講,分為本地同一臺服務器上的服務相互調用與遠程服務調用,這個都可以稱之為RPC通信。淺白點講,客戶訪問服務器A,此時服務器要完成某個動作必須訪問服務器B,服務器A與B互相通信,相互調用,

分布式系統的那些事兒 - MQ時代的通信

任務 會有 服務端 分布 ive 結果 團隊 並不會 短信 之前在講RPC通信的各種好處,特別好用,但是RPC並不是萬能的,也並不是適用於各種場景的,因為他是同步的;現如今很多場景下的調用都是異步的,系統A調用B後,並不需要知道B的結果,而且對B的結果無所謂,甚至你B掛了都

node.js學習日記node.js的作用域

ejs nodejs 文件 node 報錯 info get log 一個 node.js的作用域 測試package1能否能通過require("./package2")來調用package2內的函數: 1 //paackage1.js 2 var a1 = 1; 3

從零開始學 Web 之 JS 高級apply與call,bind,閉包和沙箱

master 操作 console 概念 釋放 分享圖片 成功 num 命名沖突 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔

Node.js學習筆記1Node.js快速開始

path 文本文 下載 啟動程序 直接 查看 學習筆記 完成後 編輯器 Node.js學習筆記(1):Node.js快速開始 Node.js的安裝 下載 官方網址:https://nodejs.org/en/ 說明:   在Windows上安裝時務必選擇全部組件,包括勾選

Node.js學習筆記2:基本模塊

依次 常用模塊 nbsp 兩個 避免 ESS 第三方 text 編程 Node.js學習筆記(2):基本模塊 模塊 引入模塊   為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件裏,這樣,每個文件包含的代碼就相對較少,很多編程語言都采用這種組織代碼的方式。在No

node.js小整理

eat 當前目錄 分享 rom js對象 mage 隊列 線程 ima node.js是一個基於Chrome v8引擎的JavaScript運行環境 之前我們編寫的JavaScript代碼都是在瀏覽器中運行的,所以我們可以直接在瀏覽器中敲代碼,然後直接運行。現在學習node

Fast MaskRCNN 框架訓練時的各種

根據上篇文章中的各種坑填平之後,可以跑訓練了,但是又又又又出現了錯誤。 明明是有GPU,但是顯示send device incarnation=1,這個值就不對了。 然後查了網上說是tensorflow 版本太高,降到1.1 由於之前的坑,所以anaconda裝了python2.7

vue.js學習筆記--父子元件通訊總結

部落格地址:https://fisher-zh.github.io 在使用Vue的過程中,如果需要進行父子元件間的通訊,通過查閱官方文件 我們可以瞭解到只需要在子元件要顯式地用 props選項宣告它期待獲得的資料,同時在其使用過程中傳入相應的資料即可,例如: Vu

關於搶火車票的那些事兒

關於搶火車票的那些事兒(三) 上一節 中我們順利登陸了12306,但是你以為這樣就順利登陸了? 那麼你就錯了。。 登陸之後你還需要進行兩步的驗證,不然在進行其他操作的時候就容易被要求重新登陸。 上一節我們收到了資料

Node.js 學習筆記1

  事件發射器會觸發事件,並且在那些事件觸發時能處理他們。事件發射器對於提高程式碼的複用性和簡潔程度至關重要。 1.Echo伺服器   Echo伺服器是一個使用事件發射器處理重複性事件的簡單例子,當你給它傳送資料時,它會把資料傳送回來。如圖1-1所示:   圖1-1 Echo伺服器響應例

d3.js學習筆記 餅圖示例

d3.testPies = function () { originalData = [30, 10, 43, 55, 13]; width = 1200; height = 200; radius = 240;

關於JAVA你必須知道的那些:繼承和訪問修飾符

今天乘著還有一些時間,把上次拖欠的面向物件程式設計三大特性中遺留的繼承和多型給簡單說明一下。這一部分還是非常重要的,需要仔細思考。 繼承 繼承:它是一種類與類之間的關係,通過使用已存在的類作為基礎來建立新類。其中已存在的類稱為父類(或基類); 建立的新類稱為子類(或派生類)。簡單的就是子類繼

教你webpack、react和node.js環境配置下篇

上篇我介紹了前端下webpack和react、redux等環境的配置,這篇將繼續重點介紹後臺node.js的配置。 我把所有程式碼都放到了我的github上:webpack-react-express環境配置 server 後臺這邊的配置就簡單了很多,我這裡拿node.js的exp

Spring boot 初步踩——Thymeleaf javaScript 聯動 數值變化

之前網上搜索 Thymeleaf 標籤 可以直接在js 裡面 獲取 action返回的值,一直在用,今天突然出現了一個奇葩問題,一個時間戳字串,java後臺列印是20180917161154369 通過js 再傳回去就成了2018091716115438了

【音樂App】—— Vue2.0開發移動端音樂WebApp專案爬

前言:在學習《慕課網音樂App》課程的過程中,第一次接觸並實踐了資料的跨域抓取和圍繞音樂播放展開的不同功能,也是這個專案帶給我最大的收穫,前面的實踐記錄分別總結了:推薦頁面開發和歌手頁面開發。這一篇主要梳理一下:音樂播放器的開發。專案github地址:https://github.com/66Web/ljq_