비동기 함수 호출을 Node.js 또는 Javascript의 동기화 함수로 래핑하는 방법은 무엇입니까?


122

함수를 노출하는 라이브러리를 유지한다고 가정합니다 getData. 사용자는이를 호출하여 실제 데이터를 얻습니다. 내부
var output = getData();
데이터는 파일에 저장되므로 getDataNode.js 내장 fs.readFileSync. 둘 다 명백 getData하고 fs.readFileSync동기화 기능입니다. 어느 날 기본 데이터 소스를 비동기식으로 만 액세스 할 수있는 MongoDB와 같은 저장소로 전환하라는 지시를 받았습니다. 또한 사용자를 화나게하는 것을 피하라는 지시를 받았습니다. getDataAPI는 단순히 약속을 반환하거나 콜백 매개 변수를 요구하도록 변경할 수 없습니다. 두 가지 요구 사항을 어떻게 충족합니까?

콜백 / 약속을 사용하는 비동기 함수는 JavasSript와 Node.js의 DNA입니다. 사소하지 않은 JS 앱에는이 코딩 스타일이 스며들 수 있습니다. 그러나 이러한 관행은 소위 둠의 콜백 피라미드로 쉽게 이어질 수 있습니다. 더 나쁜 것은 호출 체인의 호출자의 코드가 비동기 함수의 결과에 의존하는 경우 해당 코드도 콜백 함수로 래핑되어 호출자에게 코딩 스타일 제약을 부과해야합니다. 때때로 대규모 글로벌 리팩토링을 피하기 위해 비동기 함수 (종종 타사 라이브러리에서 제공됨)를 동기화 함수로 캡슐화해야합니다. 이 주제에 대한 솔루션을 찾는 것은 일반적으로 Node Fibers로 끝났습니다.또는 그것에서 파생 된 npm 패키지. 그러나 Fibers는 내가 직면 한 문제를 해결할 수 없습니다. Fibers의 저자가 제공 한 예조차도 결함을 설명했습니다.

...
Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

실제 출력 :

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)

Function Fiber가 실제로 비동기 함수 절전을 동기화로 전환하는 경우 출력은 다음과 같아야합니다.

wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main

JSFiddle 에서 또 다른 간단한 예제를 만들고 예상 출력을 생성하는 코드를 찾았습니다. Node.js에서만 작동하는 솔루션을 수락하므로 JSFiddle에서 작동하지 않아도 npm 패키지를 자유롭게 요구할 수 있습니다.


2
비동기 함수는 Node에서 동기식으로 만들 수 없으며 가능하더라도 그렇게해서는 안됩니다. 문제는 fs 모듈에서 파일 시스템에 대한 동기 및 비동기 액세스에 대해 완전히 별개의 기능을 볼 수 있다는 것입니다. 당신이 할 수있는 최선의 방법은 프라 미스 나 코 루틴 (ES6의 생성기)으로 비동기의 모양을 가리는 것입니다. 콜백 피라미드를 관리하려면 함수 호출에서 정의하는 대신 이름을 지정하고 비동기 라이브러리와 같은 것을 사용하십시오.
qubyte

8
dandavis에게 비동기는 구현 세부 사항을 콜 체인에 버블 링하여 때로는 글로벌 리팩토링을 강제합니다. 이는 모듈화 및 봉쇄가 중요한 복잡한 응용 분야에 해롭고 심지어 비참합니다.
abbr

4
"파멸의 콜백 피라미드"는 문제의 표현 일뿐입니다. Promise는 그것을 숨기거나 위장 할 수 있지만 진정한 문제를 해결할 수는 없습니다. 비동기 함수의 호출자가 비동기 함수의 결과에 의존하는 경우 콜백을 사용해야하며 호출자 등도 마찬가지입니다. 이것은 제약 조건을 부과하는 고전적인 예입니다. 단순히 구현 세부 사항 때문에 호출자.
abbr

1
@abbr : 비 동기화 모듈에 감사드립니다. 문제에 대한 설명은 제가 찾던 것과 정확히 일치하며 실행 가능한 솔루션을 찾을 수 없습니다. 나는 제너레이터와 이터 러블을 엉망으로 만들었지 만 당신과 같은 결론에 도달했습니다.
Kevin Jhangiani 2015 년

2
비동기 함수를 강제로 동기화하는 것은 좋은 생각거의 없다는 점에 주목할 가치가 있습니다. 당신은 거의 항상 여전히 (시퀀싱, 변수 설정 등과 같은) 동일한 효과를 달성하면서, 그대로 함수의 비동기 다움을 유지하는 더 나은 해결책을 가지고 있습니다.
Madara의 유령

답변:


104

deasync 는 JavaScript 레이어에서 Node.js 이벤트 루프를 호출하여 차단 메커니즘으로 구현 된 비동기 함수를 동기화로 전환합니다. 결과적으로 비 동기화는 전체 스레드를 차단하거나 바쁜 대기를 발생시키지 않고 후속 코드가 실행되는 것을 차단합니다. 이 모듈을 통해 jsFiddle 과제에 대한 답은 다음과 같습니다.

function AnticipatedSyncFunction(){
  var ret;
  setTimeout(function(){
      ret = "hello";
  },3000);
  while(ret === undefined) {
    require('deasync').runLoopOnce();
  }
  return ret;    
}


var output = AnticipatedSyncFunction();
//expected: output=hello (after waiting for 3 sec)
console.log("output="+output);
//actual: output=hello (after waiting for 3 sec)

(면책 조항 : 저는의 공동 저자입니다 deasync. 모듈은이 질문을 게시 한 후 생성되었으며 실행 가능한 제안을 찾지 못했습니다.)


다른 사람이 이것으로 운이 좋았습니까? 나는 그것을 작동시킬 수 없습니다.
newman

3
제대로 작동하지 않습니다. 더 많이 사용하려면이 모듈에 대한 문서를 개선해야합니다. 저자가 모듈 사용에 대한 결과가 무엇인지 정확히 알고 있는지 의심스럽고, 그렇다면 확실히 문서화하지 않습니다.
Alexander Mills

5
지금까지 github 문제 추적기에 문서화 된 확인 된 문제가 하나 있습니다. 이 문제는 Node v0.12에서 수정되었습니다. 내가 아는 나머지는 문서화 할 가치가없는 근거없는 추측 일뿐입니다. 비동기 화로 인해 문제가 발생했다고 생각되는 경우 자체 포함 된 복제 가능한 시나리오를 게시하면 조사하겠습니다.
abbr

나는 그것을 사용하려고 노력했고 내 스크립트에서 약간의 개선을 얻었지만 여전히 날짜에 운이 없었습니다. 다음 function AnticipatedSyncFunction(){ var ret; setTimeout(function(){ var startdate = new Date() //console.log(startdate) ret = "hello" + startdate; },3000); while(ret === undefined) { require('deasync').runLoopOnce(); } return ret; } var output = AnticipatedSyncFunction(); var startdate = new Date() console.log(startdate) console.log("output="+output); 과 같이 코드를 수정 했습니다. 날짜 출력에서 ​​3 초가 다를 것으로 예상됩니다!
알렉스

@abbr이는> browserified 노드 의존하지 않고 사용할 수
간디

5

npm 동기화 모듈도 있습니다. 쿼리 실행 프로세스를 동기화하는 데 사용됩니다.

동기식으로 병렬 쿼리를 실행하려면 노드가 응답을 기다리지 않기 때문에이를 수행하도록 제한합니다. 동기화 모듈은 이러한 종류의 솔루션에 매우 적합합니다.

샘플 코드

/*require sync module*/
var Sync = require('sync');
    app.get('/',function(req,res,next){
      story.find().exec(function(err,data){
        var sync_function_data = find_user.sync(null, {name: "sanjeev"});
          res.send({story:data,user:sync_function_data});
        });
    });


    /*****sync function defined here *******/
    function find_user(req_json, callback) {
        process.nextTick(function () {

            users.find(req_json,function (err,data)
            {
                if (!err) {
                    callback(null, data);
                } else {
                    callback(null, err);
                }
            });
        });
    }

참조 링크 : https://www.npmjs.com/package/sync


4

Function Fiber가 실제로 비동기 함수 절전을 동기화로 전환하는 경우

예. 파이버 내부에서 함수는 로깅하기 전에 기다립니다 ok. 파이버는 비동기 함수를 동기식으로 만들지 않지만 비동기 함수를 사용하는 동기식 코드를 작성할 수 있으며 Fiber.

때때로 대규모 글로벌 리팩토링을 피하기 위해 비동기 함수를 동기화 함수로 캡슐화해야하는 경우가 있습니다.

당신은 할 수 없습니다. 비동기 코드를 동기식으로 만드는 것은 불가능합니다. 글로벌 코드에서이를 예상하고 처음부터 비동기 스타일로 작성해야합니다. 전역 코드를 광섬유로 래핑하든, 약속, 약속 생성기 또는 간단한 콜백을 사용하는지 여부는 기본 설정에 따라 다릅니다.

내 목표는 데이터 수집 방법이 동기화에서 비동기로 변경 될 때 호출자에게 미치는 영향을 최소화하는 것입니다.

약속과 섬유 모두 그렇게 할 수 있습니다.


1
이것은 Node.js로 할 수있는 최악의 상황입니다. "비동기 함수를 사용하고 비동기 적으로 실행되는 동기식 코드"입니다. API가 그렇게한다면 삶을 망칠 것입니다. 비동기 인 경우 콜백이 필요하고 콜백이 제공되지 않으면 오류가 발생합니다. 사람들을 속이는 것이 목표가 아니라면 API를 만드는 가장 좋은 방법입니다.
Alexander Mills

@AlexMills : 예, 정말 끔찍할 것 입니다. 그러나 운 좋게도 이것은 API가 할 수있는 것이 아닙니다. 비동기 API는 항상 콜백을 수락하고 / 약속을 반환하고 / 파이버 내부에서 실행될 것으로 예상해야합니다. 없이는 작동하지 않습니다. Afaik, fiber는 대부분 차단되고 동시성이 없지만 비동기 API를 사용하려는 빠르고 더러운 스크립트에 사용되었습니다. 노드에서와 마찬가지로 때때로 동기식 fs메서드를 사용하는 경우가 있습니다 .
Bergi

2
나는 일반적으로 노드를 좋아합니다. 특히 순수한 js 대신 typescript를 사용할 수 있다면. 하지만 당신이하는 모든 일에 스며 들고 단일 비동기 호출을하기로 결정하자마자 말 그대로 콜 체인의 모든 기능을 감염시키는 이 전체 비동기 넌센스 는 제가 정말 싫어하는 것입니다. 비동기 API는 전염병과 같으며 한 번의 호출로 전체 코드 기반을 감염시켜 보유한 모든 코드를 다시 작성해야합니다. 나는 이것이 어떻게 이것이 좋은 것이라고 주장 할 수 있는지 정말로 이해하지 못한다 .
Kris

@Kris Node는 빠르고 간단 하기 때문에 IO 작업에 비동기 모델을 사용합니다 . 동기식으로도 많은 작업을 수행 할 수 있지만 동시에 수행 할 수 없기 때문에 차단 속도가 느립니다. 스레드를 사용하지 않는 한 모든 작업이 복잡해집니다.
Bergi

@Bergi 선언문을 읽었으므로 인수를 알았습니다. 그러나 동기화에 해당하지 않는 첫 번째 API 호출을 쳤을 때 기존 코드를 비동기로 변경하는 것은 간단 하지 않습니다 . 모든 것이 깨지고 모든 코드 줄을 면밀히 조사해야합니다. 코드가 사소한 것이 아니라면 모든 것을 비동기 관용구로 변환 한 후 변환하고 다시 작동하는 데 시간이 걸립니다.
Kris

2

약속을 사용해야합니다.

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async () => {
    return await asyncOperation();
}

const topDog = () => {
    asyncFunction().then((res) => {
        console.log(res);
    });
}

저는 화살표 함수 정의를 더 좋아합니다. 그러나 "() => {...}"형식의 모든 문자열은 "function () {...}"으로 작성 될 수도 있습니다.

따라서 topDog는 비동기 함수를 호출하더라도 비동기가 아닙니다.

여기에 이미지 설명 입력

편집 : 동기화 함수 내부에 비동기 함수를 래핑하는 데 필요한 많은 시간이 컨트롤러 내부에 있음을 알고 있습니다. 이러한 상황을 위해 파티 트릭이 있습니다.

const getDemSweetDataz = (req, res) => {
    (async () => {
        try{
            res.status(200).json(
                await asyncOperation()
            );
        }
        catch(e){
            res.status(500).json(serviceResponse); //or whatever
        }
    })() //So we defined and immediately called this async function.
}

이를 콜백과 함께 활용하면 promise를 사용하지 않는 랩핑을 수행 할 수 있습니다.

const asyncOperation = () => {
    return new Promise((resolve, reject) => {
        setTimeout(()=>{resolve("hi")}, 3000)
    })
}

const asyncFunction = async (callback) => {
    let res = await asyncOperation();
    callback(res);
}

const topDog = () => {
    let callback = (res) => {
        console.log(res);
    };

    (async () => {
        await asyncFunction(callback)
    })()
}

이 트릭을 EventEmitter에 적용하면 동일한 결과를 얻을 수 있습니다. 콜백을 정의한 EventEmitter의 리스너를 정의하고 콜백을 호출 한 이벤트를 내 보냅니다.


1

노드 파이버로 해결할 수없는 시나리오를 찾을 수 없습니다. node-fibers를 사용하여 제공 한 예제는 예상대로 작동합니다. 핵심은 파이버 내부에서 모든 관련 코드를 실행하는 것이므로 임의의 위치에서 새 파이버를 시작할 필요가 없습니다.

예를 들어 보겠습니다. 애플리케이션의 진입 점 인 일부 프레임 워크를 사용한다고 가정합니다 (이 프레임 워크는 수정할 수 없음). 이 프레임 워크는 nodejs 모듈을 플러그인으로로드하고 플러그인에서 일부 메소드를 호출합니다. 이 프레임 워크는 동기 함수 만 허용하고 광섬유 자체를 사용하지 않는다고 가정 해 보겠습니다.

플러그인 중 하나에서 사용하려는 라이브러리가 있지만이 라이브러리는 비동기 적이며 수정하고 싶지도 않습니다.

파이버가 실행되지 않으면 메인 스레드를 생성 할 수 없지만 파이버를 사용하여 플러그인을 만들 수 있습니다! 파이버 내부에서 전체 프레임 워크를 시작하는 래퍼 항목을 생성하기 만하면 플러그인에서 실행을 생성 할 수 있습니다.

단점 : 프레임 워크를 사용하는 경우 setTimeout또는 Promise내부이야, 그때는 섬유 문맥을 탈출합니다. 이것은 조롱하여 해결할 수 있습니다 setTimeout.Promise.then 모든 이벤트 핸들러.

그래서 이것이 a Promise가 해결 될 때까지 섬유를 생산할 수있는 방법 입니다. 이 코드는 비동기 (Promise returning) 함수를 사용하고 promise가 해결되면 광섬유를 다시 시작합니다.

framework-entry.js

console.log(require("./my-plugin").run());

async-lib.js

exports.getValueAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Async Value");
    }, 100);
  });
};

my-plugin.js

const Fiber = require("fibers");

function fiberWaitFor(promiseOrValue) {
  var fiber = Fiber.current, error, value;
  Promise.resolve(promiseOrValue).then(v => {
    error = false;
    value = v;
    fiber.run();
  }, e => {
    error = true;
    value = e;
    fiber.run();
  });
  Fiber.yield();
  if (error) {
    throw value;
  } else {
    return value;
  }
}

const asyncLib = require("./async-lib");

exports.run = () => {
  return fiberWaitFor(asyncLib.getValueAsync());
};

my-entry.js

require("fibers")(() => {
  require("./framework-entry");
}).run();

실행 node framework-entry.js하면 오류가 발생 Error: yield() called with no fiber running합니다.. 실행 node my-entry.js하면 예상대로 작동합니다.


0

Node.js 코드 동기화는 데이터베이스와 같은 몇 가지 측면에서 필수적입니다. 그러나 Node.js의 실제 장점은 비동기 코드에 있습니다. 단일 스레드 비 차단이므로.

중요한 기능을 사용하여 동기화 할 수 있습니다. Fiber () await ()를 사용하고 defer ()를 사용하여 await ()를 사용하여 모든 메서드를 호출합니다. 그런 다음 콜백 함수를 defer ()로 바꿉니다.

Normal Async code. CallBack 기능을 사용합니다.

function add (var a, var b, function(err,res){
       console.log(res);
});

 function sub (var res2, var b, function(err,res1){
           console.log(res);
    });

 function div (var res2, var b, function(err,res3){
           console.log(res3);
    });

Fiber (), await () 및 defer ()를 사용하여 위 코드를 동기화합니다.

fiber(function(){
     var obj1 = await(function add(var a, var b,defer()));
     var obj2 = await(function sub(var obj1, var b, defer()));
     var obj3 = await(function sub(var obj2, var b, defer()));

});

이것이 도움이되기를 바랍니다. 감사합니다


0

오늘날이 생성기 패턴은 많은 상황에서 솔루션이 될 수 있습니다.

다음은 비동기 readline.question 함수를 사용하는 nodejs의 순차 콘솔 프롬프트의 예입니다.

var main = (function* () {

  // just import and initialize 'readline' in nodejs
  var r = require('readline')
  var rl = r.createInterface({input: process.stdin, output: process.stdout })

  // magic here, the callback is the iterator.next
  var answerA = yield rl.question('do you want this? ', r=>main.next(r))    

  // and again, in a sync fashion
  var answerB = yield rl.question('are you sure? ', r=>main.next(r))        

  // readline boilerplate
  rl.close()

  console.log(answerA, answerB)

})()  // <-- executed: iterator created from generator
main.next()     // kick off the iterator, 
                // runs until the first 'yield', including rightmost code
                // and waits until another main.next() happens

-1

광섬유를 생성하는 호출 주변 에서 일어나는 일을 보는 것이 아니라 내부 에서 일어나는 일을 살펴 봐야합니다. 광섬유 . 광섬유 내부에 있으면 동기화 스타일로 프로그래밍 할 수 있습니다. 예를 들면 :

function f1 () {
    console.log ( 'wait ...'+ 새 날짜);
    수면 (1000);
    console.log ( 'ok ...'+ 새 날짜);   
}

function f2 () {
    f1 ();
    f1 ();
}

Fiber (function () {
    f2 ();
}).운영();

섬유 내부 당신은 전화 f1, f2그리고 sleep것처럼 그들은 동기했다.

일반적인 웹 애플리케이션에서는 HTTP 요청 디스패처에 Fiber를 생성합니다. 이 작업을 마치면 비동기 함수 (fs, 데이터베이스 등)를 호출하더라도 모든 요청 처리 논리를 동기화 스타일로 작성할 수 있습니다.


고마워 브루노. 그러나 서버가 tcp 포트에 바인딩하기 전에 실행되어야하는 부트 스트랩 코드에서 동기화 스타일이 필요한 경우-예를 들어 비동기로 열린 db에서 읽어야하는 데이터 또는 구성은? 나는 전체 server.js를 Fiber로 래핑하는 것으로 끝날 수 있으며 전체 프로세스 수준에서 동시성을 죽일 것이라고 생각합니다. 그럼에도 불구하고 검증 할 가치가있는 제안입니다. 나에게 이상적인 솔루션은 비동기 함수를 래핑하여 동기화 호출 구문을 제공하고 프로세스 수준에서 동시성을 희생하지 않고 호출자 체인의 다음 코드 줄만 차단할 수 있어야합니다.
abbr

하나의 큰 Fiber 호출에 전체 부트 스트랩 코드를 래핑 할 수 있습니다. 일반적으로 요청 처리를 시작하기 전에 부트 스트랩 코드가 완료 될 때까지 실행되어야하므로 동시성은 문제가되지 않아야합니다. 또한 섬유는 다른 섬유가 실행되는 것을 방지하지 않습니다. yield 콜을 할 때마다 다른 섬유 (및 주 스레드)가 실행될 기회를 제공합니다.
Bruno Jouhier 2014

Express 부트 스트랩 파일 server.js를 파이버로 래핑했습니다. 실행 순서는 내가 찾고있는 것이지만 그 랩은 요청 핸들러에 영향을 미치지 않습니다. 그래서 각 디스패처에 동일한 래퍼를 적용해야한다고 생각합니다. 글로벌 리팩토링을 피하는 데 더 나은 방법이없는 것 같기 때문에이 시점에서 포기했습니다. 내 목표는 데이터 수집 방법이 DAO 계층에서 동기화에서 비동기로 변경되고 Fiber가 여전히 도전에 약간 부족할 때 호출자에게 미치는 영향을 최소화하는 것입니다.
abbr

@fred : 요청 핸들러처럼 이벤트 스트림을 "동기화"하는 것은 의미가 없습니다 while(true) handleNextRequest(). 루프 가 필요합니다 . 각 요청 핸들러를 광섬유로 래핑하면됩니다.
Bergi

@fred : Fiber는 Express의 콜백이 연속 콜백 (오류 또는 결과와 함께 항상 정확히 한 번 호출되는 콜백)이 아니기 때문에 Express에서 많은 도움이 되지 않습니다 . 그러나 연속 콜백 (fs, mongodb 및 기타 여러 가지)을 사용하여 비동기 API 위에 많은 코드를 작성하면 파이버가 운명의 피라미드를 해결할 것입니다.
Bruno Jouhier 2014

-2

처음에는 node.js로이 문제를 해결했으며 async.js는이 문제를 처리하는 데 도움이되는 최고의 라이브러리입니다. 노드를 사용하여 동기 코드를 작성하려면이 방법이 있습니다.

var async = require('async');

console.log('in main');

doABunchOfThings(function() {
  console.log('back in main');
});

function doABunchOfThings(fnCallback) {
  async.series([
    function(callback) {
      console.log('step 1');
      callback();
    },
    function(callback) {
      setTimeout(callback, 1000);
    },
    function(callback) {
      console.log('step 2');
      callback();
    },
    function(callback) {
      setTimeout(callback, 2000);
    },
    function(callback) {
      console.log('step 3');
      callback();
    },
  ], function(err, results) {
    console.log('done with things');
    fnCallback();
  });
}

이 프로그램은 항상 다음을 생성합니다 ...

in main
step 1
step 2
step 3
done with things
back in main

2
async귀하의 예제에서 작동합니다 b / c 그것은 main발신자에 대해 신경 쓰지 않습니다. 모든 코드가 비동기 함수 호출 중 하나의 결과를 반환해야하는 함수에 래핑되어 있다고 상상해보십시오. console.log('return');코드 끝에 추가하여 작동하지 않는 것을 쉽게 증명할 수 있습니다 . 이러한 경우의 출력은 return이후에 일어날 것입니다 in main하지만 전에 step 1.
abbr

-11

Javascript는 단일 스레드 언어이므로 전체 서버를 차단하고 싶지 않습니다! 비동기 코드는 종속성을 명시 적으로 만들어 경쟁 조건을 제거합니다.

비동기 코드를 사랑하는 법을 배우십시오!

promises콜백 지옥의 피라미드를 만들지 않고 비동기 코드를 살펴보십시오 . node.js 용 promiseQ 라이브러리를 권장합니다.

httpGet(url.parse("http://example.org/")).then(function (res) {
    console.log(res.statusCode);  // maybe 302
    return httpGet(url.parse(res.headers["location"]));
}).then(function (res) {
    console.log(res.statusCode);  // maybe 200
});

http://howtonode.org/promises

편집 : 이것은 지금까지 가장 논란이 많은 대답입니다. 노드는 이제 yield 키워드를 가지고있어 비동기 코드를 동기식 인 것처럼 처리 할 수 ​​있습니다. http://blog.alexmaccaw.com/how-yield-will-transform-node


1
Promise는 함수를 동기화하지 않고 콜백 매개 변수 만 변경합니다.
abbr

2
동기화를 원하지 않으면 전체 서버가 차단됩니다! stackoverflow.com/questions/17959663/…
roo2 2014

1
바람직한 것은 Node.js가 처리하는 다른 요청과 같은 다른 이벤트를 차단하지 않고 동기화 호출하는 것입니다. 정의상 Sync 함수는 결과가 생성 될 때까지 호출자에게 반환되지 않는다는 의미 일뿐입니다 (단순히 약속이 아님). 호출이 차단되는 동안 다른 이벤트를 처리하지 못하도록 서버를 미리 제외하지 않습니다.
abbr

@fred : 나는 당신이 약속의 요점을 놓치고 있다고 생각 합니다 . 단순히 관찰자 패턴 추상화가 아니라 비동기 작업을 연결하고 구성하는 방법을 제공합니다.
Bergi

1
@Bergi, 나는 약속을 많이 사용하고 그것이 무엇을하는지 정확히 알고 있습니다. 효과적으로 달성 된 모든 것은 단일 비동기 함수 호출을 여러 호출 / 문으로 분해하는 것입니다. 그러나 결과는 변경되지 않습니다. 호출자가 반환하면 비동기 함수의 결과를 반환 할 수 없습니다. 내가 JSFiddle에 게시 한 예제를 확인하십시오. 이 경우 호출자는 AnticipatedSyncFunction 함수이고 비동기 함수는 setTimeout입니다. 약속을 사용하여 내 도전에 답할 수 있다면 보여주세요.
abbr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.