0

我只是对 Javascript 有一个一般性的问题。如果我必须为 UI 调用两个服务,并且这两个服务调用有自己的回调,但 UI 模板必须在两个回调完成执行后才呈现,那么最好的 Javascript 实践应该是什么?

invokeServices() {
    invokeService1(param1, param2, svcCallback1);
    invokeService2(param1, param2, svcCallback2);
    //where to render the template???
}

function svcCallback1 (){
    //where to render the template???

}

function svcCallback2 (){
    //where to render the template???

}
4

2 回答 2

2

这篇文章可能会有所帮助:Marko vs React:深入了解。具体来说,查找有关Async如何使用承诺和<await/>标签来延迟渲染直到所有数据都存在的部分。

import fsp from 'fs-promise';

$ var filePath = __dirname + '/hello.txt';
$ var readPromise = fsp.readFile(filePath, {encoding: 'utf8'});

<await(helloText from readPromise)>
  <p>
    ${helloText}
  </p>
</await>
于 2018-08-07T23:10:05.930 回答
1

1. 跟踪回调的完成情况

function invokeServicesAndRender() {
  let remaining = 2;
  let service1Data;
  let service2Data;

  invokeService1(param1, param2, (err, data) => {
     service1Data = data;
     if (!--remaining) done();
  });

  invokeService2(param1, param2, (err, data) => {
     service2Data = data;
     if (!--remaining) done();
  });

  function done() {
     // all data is here now, we can render the ui
  }
}

2. Promisify 和使用Promise.all

Node 有一个内置的方法来承诺回调:util.promisify

const promisify = require('util').promisify;
const promiseService1 = promisify(invokeService1);
const promiseService2 = promisify(invokeService2);

function invokeServicesAndRender() {
  Promise.all([
    promiseService1(param1, param2),
    promiseService2(param1, param2),
  ]).then(([service1Data, service2Data]) => {
    // all data is here now, we can render the ui
  });
}

3. 如果您使用 Marko,请立即渲染并将 Promise 传递给模板

我看到你标记了这个问题marko,所以我会提到,对于 Marko,建议立即开始渲染,只等待渲染实际需要数据的块。这使您可以更快地向用户刷新内容。

const promisify = require('util').promisify;
const promiseService1 = promisify(invokeService1);
const promiseService2 = promisify(invokeService2);

function invokeServicesAndRender() {
  let service1DataPromise = promiseService1(param1, param2);
  let service2DataPromise = promiseService2(param1, param2);
  template.render({ service1DataPromise, service2DataPromise });
}

在您的模板中,您可以使用<await>标签在需要的地方等待数据:

<h1>Hello World</h1>
<p>this content gets rendered immediately</p>

<await(service1Data from input.service1DataPromise)>
  <!-- render content here that needs the service data -->
</await>
于 2018-08-07T23:26:29.680 回答