When I use async await in javascript, there was problem that results were not in sequential order. Find out reason and solution for it.


Environment and Prerequisite

  • Javascript
  • async and await
  • Python
  • Flask


Before In

  • Briefly explain about async await and test environment.

async await

async

  • Asynchronous function define keyword
  • Add it to use below await.

await

  • It waits Promise object and can be used in async function.
  • Wait until Promise becomes resolve or reject.
  • In simple terms, it is a keyword which waits until response of asynchronous request comes.

Examples

function timer(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function test() {
  var x = await timer(10); // wait 2000 milliseconds
  console.log(x); // 10
}

test();


Test Environment

  • Send client’s id and server returns it
  • Server is written in python but there is no problem with understanding because we only focus on client code.

Test Structure

Server Code

from flask import Flask, request
import json
import time

app = Flask(__name__)

host_addr = "0.0.0.0"
port_num = "8080"

@app.route("/test", methods = ['POST'])
def test():
    print("Time:" + str(int(round(time.time() * 1000))) + ", reqeust from client : " + str(request.json['data']))
    return str(request.json['data'])

if __name__ == "__main__":
    app.run(host = host_addr, port = port_num)


Issue

  • Response does not come sequentially when we use forEach..

Request Code

arr = [1, 2, 3, 4];

arr.forEach(async (i) => {
  const response = await axios.post("http://0.0.0.0:8080/test", {
      data: i,
  });
  console.log("forEachRequestUsingAsyncAwait server response: " + response.data);
});

Response

  • Responses are not sequential.
$ node test.js
forEachRequestUsingAsyncAwait server response: 1
forEachRequestUsingAsyncAwait server response: 4
forEachRequestUsingAsyncAwait server response: 3
forEachRequestUsingAsyncAwait server response: 2

Server Log

  • Requests are not sequential.
Time:1602409922301, reqeust from client : 1
127.0.0.1 - - [11/Oct/2020 18:52:02] "POST /test HTTP/1.1" 200 -
Time:1602409922302, reqeust from client : 4
127.0.0.1 - - [11/Oct/2020 18:52:02] "POST /test HTTP/1.1" 200 -
Time:1602409922303, reqeust from client : 3
127.0.0.1 - - [11/Oct/2020 18:52:02] "POST /test HTTP/1.1" 200 -
Time:1602409922303, reqeust from client : 2
127.0.0.1 - - [11/Oct/2020 18:52:02] "POST /test HTTP/1.1" 200 -


Reason

Reason

  • forEach calls a provided callback function once for each element in an array in ascending order. Callback runs in sequential but it does not wait until one is finished.
  • That is because it runs not like iteration which runs next step when one step is finished. It runs each callback.

Documents

Array.prototype.forEach ( callbackfn [ , thisArg ] )
  • According to ECMAScript Language Specification, it says “callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each element present in the array, in ascending order. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.”
arr.forEach(callback(currentValue[, index[, array]]) {
  // execute something
}[, thisArg]);
  • According to MDN Web Docs, it says “forEach() calls a provided callback function once for each element in an array in ascending order.”


Solutions

Use for-in or for-of

for-in

  • Request code
async function forInRequest () {
  for (const i in arr){
    const response = await axios.post("http://0.0.0.0:8080/test", {
        data: arr[i],
    });
    console.log("forInRequest server: " + response.data);
  }
}

forInRequest();
  • Response result
node test.js
forInRequest server: 1
forInRequest server: 2
forInRequest server: 3
forInRequest server: 4
  • Server response result
Time:1603631271374, reqeust from client : 1
127.0.0.1 - - [25/Oct/2020 22:07:51] "POST /test HTTP/1.1" 200 -
Time:1603631271383, reqeust from client : 2
127.0.0.1 - - [25/Oct/2020 22:07:51] "POST /test HTTP/1.1" 200 -
Time:1603631271386, reqeust from client : 3
127.0.0.1 - - [25/Oct/2020 22:07:51] "POST /test HTTP/1.1" 200 -
Time:1603631271388, reqeust from client : 4
127.0.0.1 - - [25/Oct/2020 22:07:51] "POST /test HTTP/1.1" 200 -

for-of

  • Request code
async function forOfRequest () {
  for (const i of arr){
    const response = await axios.post("http://0.0.0.0:8080/test", {
        data: i,
    });
    console.log("forOfRequest server: " + response.data);
  }
}

forOfRequest();
  • Response result
node test.js
forOfRequest server: 1
forOfRequest server: 2
forOfRequest server: 3
forOfRequest server: 4
  • Server response result
Time:1603631202328, reqeust from client : 1
127.0.0.1 - - [25/Oct/2020 22:06:42] "POST /test HTTP/1.1" 200 -
Time:1603631202335, reqeust from client : 2
127.0.0.1 - - [25/Oct/2020 22:06:42] "POST /test HTTP/1.1" 200 -
Time:1603631202338, reqeust from client : 3
127.0.0.1 - - [25/Oct/2020 22:06:42] "POST /test HTTP/1.1" 200 -
Time:1603631202342, reqeust from client : 4
127.0.0.1 - - [25/Oct/2020 22:06:42] "POST /test HTTP/1.1" 200 -


Reference

“SyntaxError: Non-ASCII character …, but no encoding declared”와 같은 이슈가 생겼을 때 해결 방법을 알아보자


환경

  • Python


문제와 해결 방법

문제 상황

  • 파이썬 코드를 실행했는데 아래와 같은 오류를 보여준다.
python /home/twpower/MailReminder/reminder.py
...
SyntaxError: Non-ASCII character '\xeb' in file /home/twpower/MailReminder/reminder.py on line 12, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details


원인

  • 실행중인 코드에 ASCII가 아닌 문자가 들어있는데 인코딩을 명시해주지 않아서 생기는 오류


해결 방법

  • 파이썬 파일 제일 상단에 # -*- coding: utf-8 -*-를 추가한다.
# -*- coding: utf-8 -*-
...


참고자료

Solution for “SyntaxError: Non-ASCII character …, but no encoding declared”


Environment and Prerequisite

  • Python


Problem and Solution

Issue

  • Error comes out like below when running python code.
python /home/twpower/MailReminder/reminder.py
...
SyntaxError: Non-ASCII character '\xeb' in file /home/twpower/MailReminder/reminder.py on line 12, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details


Cause

  • Issue which there was non ascii character in running code but encoding was not declared


Solution

  • Add # -*- coding: utf-8 -*- to top of python code file.
# -*- coding: utf-8 -*-
...


Reference

undefined와 null의 차이를 알아보자


환경

  • Javascript


undefined와 null

undefined

  • 변수가 값을 할당받지 않았을 때 사용되는 원시 값(primitive value)입니다.
  • 함수의 반환이 명시적으로 없으면 undefined를 반환합니다.
  • 원시 자료형 중 하나
// test default
let test;
console.log('variable test is ' + test);

// if statement
if (test === undefined) {
  console.log('variable test is ' + test);
}

// if statement
if (undefined) {
  console.log('undefined is considered as true');
} else {
  console.log('undefined is considered as false');
}

// type test in if statement
// return type of typeof function is string
if (typeof(test) === 'undefined') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNothing() {
  let c;
}
console.log('testReturnNothing returns ' + testReturnNothing());

// check which is not defined
if (typeof(notDefinedVariable) === 'undefined') {
  console.log('variable notDefinedVariable is not defined');
}
variable test is undefined
variable test is undefined
undefined is considered as false
variable test value is undefined and type is undefined
testReturnNothing returns undefined
variable notDefinedVariable is not defined


null

  • 의도적으로 객체나 변수가 비어있음을 나타내는 원시 값입니다.
  • API에서는 대개 객체를 기대했지만, 어떤 적합한 객체도 존재하지 않을 때 반환합니다.
  • 불리언(Boolean) 자료형에서는 거짓을 의미합니다.
// test default
let test = null;
console.log('variable test is ' + test);

// if statement
if (test === null) {
  console.log('variable test is ' + test);
}

// if statement
if (null) {
  console.log('null is considered as true');
} else {
  console.log('null is considered as false');
}

// type test in if statement
// return type of typeof function is string
// its return type is not 'null' it is 'object'
if (typeof(test) === 'object') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNull() {
  return null;
}
console.log('testReturnNull returns ' + testReturnNull());
variable test is null
variable test is null
null is considered as false
variable test value is null and type is object
testReturnNull returns null


비교

undefined

  • 아직 할당되지 않았음을 의미하는 값

null

  • 의도적으로 비어있음을 나타내는 값

기타

  • ==를 사용 시 둘은 같으며 ===를 사용 시 둘은 다릅니다.
  • ===의 경우에 type까지 같이 비교하기 때문에 그렇습니다. 각각의 type은 아래처럼 다릅니다.
typeof(null)         // object
typeof(undefined)    // undefined

null === undefined   // false
null == undefined    // true

!null                // true
!undefined           // true


참고자료

Difference between undefined and null


Environment and Prerequisite

  • Javascript


undefined and null

undefined

  • It is a primitive value used when a variable has not been assigned a value.
  • A function returns undefined if explicitly nothing is returned.
  • One of primitive types
// test default
let test;
console.log('variable test is ' + test);

// if statement
if (test === undefined) {
  console.log('variable test is ' + test);
}

// if statement
if (undefined) {
  console.log('undefined is considered as true');
} else {
  console.log('undefined is considered as false');
}

// type test in if statement
// return type of typeof function is string
if (typeof(test) === 'undefined') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNothing() {
  let c;
}
console.log('testReturnNothing returns ' + testReturnNothing());

// check which is not defined
if (typeof(notDefinedVariable) === 'undefined') {
  console.log('variable notDefinedVariable is not defined');
}
variable test is undefined
variable test is undefined
undefined is considered as false
variable test value is undefined and type is undefined
testReturnNothing returns undefined
variable notDefinedVariable is not defined


null

  • It is a primitive value that represents the intentional absence of any object value.
  • In APIs, null is often retrieved in a place where an object can be expected but no object is relevant.
  • Treated as falsy for boolean operations.
// test default
let test = null;
console.log('variable test is ' + test);

// if statement
if (test === null) {
  console.log('variable test is ' + test);
}

// if statement
if (null) {
  console.log('null is considered as true');
} else {
  console.log('null is considered as false');
}

// type test in if statement
// return type of typeof function is string
// its return type is not 'null' it is 'object'
if (typeof(test) === 'object') {
  console.log('variable test value is ' + test + ' and type is ' + typeof(test));
}

// function return
function testReturnNull() {
  return null;
}
console.log('testReturnNull returns ' + testReturnNull());
variable test is null
variable test is null
null is considered as false
variable test value is null and type is object
testReturnNull returns null


Comparison

undefined

  • Value which represents not defined yet

null

  • Intentional value that it is absence

etc

  • It is equal when use == operator but it will be not equal when use === operator.
  • Because === operator compare not only value but also type. Its type is different like below.
typeof(null)         // object
typeof(undefined)    // undefined

null === undefined   // false
null == undefined    // true

!null                // true
!undefined           // true


Reference